在 Windows 下用 GCC 编译器练习 C/C++ 的简单教程
入门
技术
2024年9月更新:
本文自 17 年写好至今,已将近八年,计算机发展到当下,情况有些变化,虽然方法上仍然还是相通的,但在具体操作上与实际情况多少会有些出入,对于新手朋友而言,可以优先关注 Wiki 以及楼下最新的帖子更新。
毕业工作已好几年,很难再从新生视角去写一些东西啦,所以也建议有余力的新生朋友,在配好环境之后,可以考虑做些总结、笔记等记录一下,多与身边人交流分享。开发环境这事情需要的是多尝试,然后找到合适自己的状态。
2018年8月更新:
这个暑假博主和小伙伴、老师一同为师弟师妹们折腾了一个关于计算机学习交流的小社区 0xFFFF ,经过一个暑假的积淀,留下了不少适合计算机入门阅读的内容,推荐给看到这篇文章的你。
以下是正文:
最近有许多师弟师妹们问入门 C 语言和 C++ 的时候练习代码应该装什么软件。
根据老师和前辈们的建议以及我这一年的折腾经验,在 Linux 系统下学习 C 语言和 C++ 的话那真是极好的,但是鉴于现实的情况(例如 Linux 命令行操作对于一个暂时对电脑不是非常了解的人来说可能一开始不太好上手),很多东西还是需要在 Windows 下进行。
在 Windows 下编程,大多数人用的是“宇宙最强IDE”—— Visual Studio (ps: IDE 是集成开发环境的简称),VS 的确好用,基本把你需要的东西都准备好了,然而装过的人都知道,装这东西有时候可以折腾你一下午,没设置好的话可能一下子装了几 GB 现在的我们还不知道是拿来干什么的东西。
师兄推荐了 Code::Blocks 这个相比 VS 更简洁的IDE,但我觉得可以更简单。
所以我推荐 文本编辑器 + GCC 编译器 这个无敌组合,在入门阶段基本能够满足使用。
为什么用这个组合而不是直接上IDE
关注本质
首先我们得对 C 语言/ C++ 程序的运行流程有一个基本的认识,从 Think-C 的1.1节我们可以知道。C/C++的源代码 (source code) 需要经过编译 (compiling) 这个过程转换为二进制可执行文件才能运行。
本质上来说,其实所有的 C、C++、Java、Python 等语言的源代码(对应的源文件后缀分别为.c .cpp .java .py等)都属于文本文件,除了后缀名之外没有其它差别,所以它们都可以通过文本编辑器编辑。
写好代码,通过编译器把代码编译成可执行文件,写的程序就能运行了。
所以说,入门 C语言/ C++ 编程,实际上我们只需要两个工具:文本编辑器、编译器。其它的诸如调试器等工具都是围绕着它们工作的。
类似 Visual Studio,Code::Blocks 这样的 IDE ,它也可以说是文本编辑器以及编译器和调试器等等工具的结合体,它们是为了高效解决工程问题的产物。
为了工程上的效率,IDE隐藏了许多细节,通过IDE入门编程,点击编译按钮的背后,IDE为我们做了什么事情,我们并不容易注意到,且初学时我们也用不上太复杂的东西,刚开始就使用过于大而全的工具容易陷入迷茫。例如 Visual Studio 里“解决方案资源管理器”之类的界面,还有装 Visual Studio 的时候装上的各种各样奇奇怪怪的组件(实际上它们都不是重点)。
我们写代码总不可能依赖于某个编程工具,所以趁现在写的东西还不复杂的时候,多多了解、亲身体验一下那些相对更底层的东西,对我们的发展是很有帮助的。
以后我们写相对复杂的项目,基本的功能满足不了我们的需要的时候,再选择一个强大的 IDE 来帮助我们更好地组织管理我们的代码,我认为这是一个适合初学者的较为平缓的学习路径。
通过GCC的使用初步了解命令行
入门阶段的我们写的程序基本是在命令行(又叫终端)下运行的,即使你直接在Windows的图形界面下运行这些程序,系统还是要弹出一个命令行窗口为它提供一个运行的环境,熟悉命令行的重要性不言而喻。
GCC全套工具都是在命令行下使用的,还有许多优秀的工具和程序,例如 Python 解释器、Node.js 以及依赖 Node.js 的一系列网页前端开发的构建工具、以后工作或参与开源项目时肯定会用到的 Git,SVN 等版本控制工具等等,也是在命令行下运行的。在使用GCC的过程中我们可以收获很多关于命令行的概念和使用技巧,对命令行有一个初步的印象。
学习计算机,我们无可避免的要接触到 Linux 操作系统。通过 GCC 编译器的使用,也可以为我们熟悉 Linux 建立一点基础。Linux 内核作为 Unix 内核的开源实现,在命令行方面的功能是非常强大的,围绕着 Linux 内核有许许多多优秀的应用程序,GCC 只是它其中的冰山一角。工具繁多,一开始总会让人感到眼花缭乱,学习曲线也相对陡峭。
平时我们可能熟悉 Windows 多一些,在 Windows 中,命令行与 Linux 有许多相似之处,从 Windows 熟悉命令行开始也可以作为一个过渡的方式。
2022年3月16日补充
这里再进阶,核心便是 MIT Missing Semester 所关注的部分
节省磁盘空间
值得关注的是,相比 VS 动辄上 GB 的空间占用,这个装完最多也就占用几百M硬盘空间,岂不美哉?
关于 GCC 的介绍
关于GCC的发展史,推荐阅读: 鸟哥的Linux私房菜
引用一段来自维基百科的解释:
GNU编译器套装(英语:GNU Compiler Collection,缩写为GCC),一套编程语言编译器,以GPL及LGPL许可证所发行的自由软件,也是GNU项目的关键部分,也是GNU工具链的主要组成部分之一。GCC(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。1985年由理查德·马修·斯托曼开始发展,现在由自由软件基金会负责维护工作。
原名为GNU C语言编译器(GNU C Compiler),因为它原本只能处理C语言。GCC很快地扩展,变得可处理C++。之后也变得可处理Fortran、Pascal、Objective-C、Java、Ada,以及Go与其他语言。
许多操作系统,包括许多类Unix系统,如Linux及BSD家族都采用GCC作为标准编译器。苹果电脑Mac OS X操作系统也采用这个编译器。
文本编辑器的选择与安装
说到文本编辑器,我们第一时间想到的应该就是记事本了,但是有一点大家要注意,不推荐使用记事本编辑代码。原因是 Windows 自带的记事本编辑的 Unicode 文本文件头部会自带 BOM,BOM 在某些环境下会出现问题,参考知乎上的这个回答 补充阅读:「带 BOM 的 UTF-8」和「无 BOM 的 UTF-8」有什么区别?网页代码一般使用哪个? - 知乎。
适合写代码用的文本编辑器有很多,这里推荐的有:Vim,Emacs,Atom,VSCode,Notepad++,Sublime Text等。我们可以多多尝试,用心去感受一下它们各自的特点,然后选一个喜欢的作为陪伴我们编程生涯的主力文本编辑器。
以上提到的文本编辑器,除了 Notepad++ 只支持 Windows 之外,其它的编辑器在 Windows,Linux,macOS 下都有各自的版本。它们都支持安装各种插件实现特定领域的强大功能,限于篇幅这里先不说了。
在这里我用的是 Atom(点击进入官网)
2018.05.09 更新
博主现在已经转投 VS Code 编辑器,VS Code 的设计对初学者也更友好一些
点击链接直达官网下载地址 https://code.visualstudio.com/Download
VSCode 安装与使用方法与 Atom 类似
由于截图的工程量较大,所以这里就不更新截图啦~
2024.09.28 更新
现在 Atom 已经不太推荐,可直接用 VSCode
鉴于海外服务器下载速度较慢的原因,建议从淘宝的 npm 源镜像里面下载最新版 Atom 安装文件,截至这篇文章发表之时它更新到了 1.19.0 版
https://npm.taobao.org/mirrors/atom/
在网页上我们可以看到有一大堆不同平台的安装文件在上面,我们下载 AtomSetup-x64.exe
下载好之后和一般的软件一样,打开安装就行,安装好后我们发现桌面多了这个图标。 说明编辑器已经可以用了。
GCC编译器的安装
GCC是个跨平台的开源的编译工具套装,自然在 Windows 下也会有相应的集成包,一般用的比较多的有 MinGW、MinGW-w64 和 TDM-GCC ,三者的区别和联系可以参考这篇博文,这里我们用的是TDM-GCC。
ps: Code::Blocks、Dev-C++ 软件默认也是使用 GCC 编译器编译代码的
打开TDM-GCC的官网 ,点击中间的 "TDM64 bundle" 下载安装包,运行安装包
点击 Create,开始一个新的安装
我们用的基本都是64位的电脑,当然是选择64位啦。
一路Next就可以了
整个安装向导跑完之后,GCC 编译器就已经在你的电脑上了,刚刚提到,这是个在命令行下运行的程序,没有图形界面。
我们先验证一下 GCC 有没有安装好。
首先随便打开一个文件夹(桌面也可),按住 shift 键,右击空白处,你会发现右键菜单多了一项“在此处打开命令窗口”,如果你安装了 Windows 10 的最新更新,你看到的会和截图一样,打开的是 PowerShell ,没关系!两个东西除了界面和一些具体的功能不一样,用起来是差不多的。
打开之后我们发现它提示了我打开的文件夹的路径,路径的后面可以通过键盘输入文字,意思是接下来的命令是基于这个文件夹路径运行的。
我们在里面输入 gcc 然后回车,如果返回了一个 fetal error: no input files 的错误提示的话,说明 gcc 已经装好并且可以使用了。
这是默认的 CMD(ps: CMD 是 Windows 希望淘汰但因为兼容旧版不得不保留的东西)
这是 PowerShell 的效果
如果返回的是“gcc 不是内部或外部命令,也不是可运行的程序或批处理文件。”的话,说明没装好,可能需要重新试一下,或者是通过重启 Windows 来使 tdm-gcc 集成包安装时给系统设置的环境变量生效。(这里涉及到了“环境变量”的概念,建议主动搜索一下,计算机就是这么一个错综复杂的知识网络呢^_^)
到这里,文本编辑器和编译器已经准备好啦,接下来我再介绍怎么用它们运行代码。
补充知识:用户在使用操作系统的过程中,需要与操作系统的内核交互,这个交互的过程,是通过“壳层”来实现的,英文名为Shell。“壳层”主要分为两类,一类是图形界面(GUI:Graphicial User Interface),另一类是命令行界面(CLI:Command-line Interface),作为一名未来的开发者,除了平常使用的图形界面外,高效精准的命令行界面是不能忽视的。PowerShell 与 CMD 一样,都属于 CLI 类型的 Shell 程序。关于 Shell 的更多概念,推荐阅读 鸟哥的 Linux 私房菜 -- 学习 bash shell。
使用方法
写代码
没有了IDE的一键编译代码按钮,自然这些操作都需要手动来,听起来很麻烦的样子?
不用担心!就算是手动,也不会麻烦,至少比你装 Visual Studio 全家桶简单。
下面让我演示一下在这个环境下,程序是怎么跑起来的。
首先第一步还是先写写源代码,打开 Atom,点击菜单栏的 File > New File 新建一个文本文件,然后File > Save 定位到一个你想用来放代码的文件夹,文件名取一个后缀为 .c 的名字就好。
保存之后就可以开始写了,写好再继续保存
接下来进入放源代码的文件夹,同样的方法,按住Shift在空白处点击右键,打开命令行窗口
这时候我们运行 gcc 把 first.c 编译成 Windows 可用的可执行文件,命令很简单
gcc first.c
ps: 如果你写的是C++,则需要用 g++ 调用GCC的C++编译器而不是 C语言编译器 gcc ,假定源文件是 first.cpp
g++ first.cpp
输入完后回车,这时候gcc开始编译你告诉它的文件了,稍等片刻,等这一条命令结束,命令行出现了新的提示符以后,编译就完成了
我们可以发现,这个文件夹多了个名为 a.exe 的程序,这就是我们编译好以后可以运行的程序了。
下一步,在命令行里面执行这个程序,输入
.\a.exe
发现 PowerShell 窗口里面输出了我想要它输出的字符串,然后程序结束了,再一次出现了新的提示符
爱动脑筋的同学可能会想,既然是个exe那我就不能双击运行么?
当然可以,那就双击打开试试!!
……
打开后发现,它弹出一个窗口,但是我还没看清它就消失了,这是为什么呢?
前文有提到过,我们写的是基于命令行的程序,如果脱离命令行环境直接运行的话,Windows 会创建一个命令行窗口给它提供一个运行的环境,这时候命令行窗口属于这个程序的进程(嗷,这里又扯到了“进程”这个概念了,不明白的话赶紧搜索一下)。这个程序启动后,执行完向命令行打印字符的操作,告诉系统,我已经顺利执行完毕啦,于是它的生命周期结束。自然,Windows 系统要把它之前申请的资源都回起来,包括那个弹出的命令行窗口,于是系统销毁了那个弹出来的命令行窗口。
当程序在命令行下运行时候,程序使用的命令行窗口属于执行它的命令行窗口的进程(CMD或者PowerShell),程序退出以后,命令行实际还是在运行的,因而窗口不会销毁,程序留下的记录仍然可以得到保留。
有没有一种双击打开程序不让命令行窗口一闪而过的方法呢?答案是肯定的。如果我们能让程序运行的时候停留在某个步骤不动,那么它就可以保持不退出啦,一般在 Windows 下我们常用的暂停语句是 system("pause"); ,这个语句是通过执行命令行的 pause 命令来实现让程序暂停的功能(和你在命令行输入 pause 回车一样的效果,建议你自己试一试),程序执行到这一步,提示“按任意键继续”,程序暂停,当你按任意键以后,程序才继续向下执行,就不会停不下来立马退出了。
错误处理
如果源代码有语法错误的话,编译时编译器会报错并且不会生成目标代码。
这里我故意把第5行最后的分号删掉,再运行 gcc 命令编译,提示第六行第五个字符的 return 之前少了分号,编译失败。
错误定位办法参考师兄的文章
至此,我们可以开始愉快地练习代码啦!
这里讲两个命令行的小技巧:一是命令行执行过的命令会有历史记录,我们可以通过按上下方向键来切换之前执行过的命令;二是我们填文件名的时候如果它太长了的话,可以先输入前面一小部分,然后按 Tab 键就可以自动补全了。
命令行中还蕴藏着无限的可能,等待着你的探索。
最后想说的
刚开始入门计算机时,可能你会对选择命令行还是图形界面、对学习编程的方式有些迷茫,这里我也试图提供一些相关的信息和我的一些想法,希望可以带来帮助。
贴一个我在知乎上看到的回答 (原文链接)
我想,学习一门编程语言,并不是像我们以前学英语那样,总是研究这个语法那个用法而脱离了实际的应用。我们作为计算机专业的学生,学这些东西并不是像别的专业那样为了考证而学,而是应该把它用起来。一门编程语言的很多特性,和实际的应用和系统的运行紧密相关。仅仅盯着语言的语法和表面的东西,大概会像我身边有一些小伙伴一样,光跟着谭浩强课本学了一年的C++语法,到现在还是一头雾水。
这里也引用一段来自 前言 - Linux C编程一站式学习 的话:
为什么要在Linux平台上学C语言?用Windows学C语言不好吗?
用Windows还真的是学不好C语言。C语言是一种面向底层的编程语言,要写好C程序,必须对操作系统的工作原理非常清楚,因为操作系统也是用C写的,我们用C写应用程序直接使用操作系统提供的接口。既然你选择了看这本书,你一定了解:Linux是一种开源的操作系统,你有任何疑问都可以从源代码和文档中找到答案,即使你看不懂源代码,也找不到文档,也很容易找个高手教你,各种邮件列表、新闻组和论坛上从来都不缺乐于助人的高手;而Windows是一种封闭的操作系统,除了微软的员工别人都看不到它的源代码,只能通过文档去猜测它的工作原理,更糟糕的是,微软向来喜欢藏着揶着,好用的功能留着自己用,而不会写到文档里公开。本书的第一部分在Linux或Windows平台上学习都可以,但第二部分和第三部分介绍了很多Linux操作系统的原理以帮助读者更深入地理解C语言,只能在Linux平台上学习。
Windows平台上的开发工具往往和各种集成开发环境(IDE,Integrated Development Environment)绑在一起,例如Visual Studio、Eclipse等。使用IDE确实很便捷,但IDE对于初学者绝对不是好东西。微软喜欢宣扬傻瓜式编程的理念,告诉你用鼠标拖几个控件,然后点一个按钮就可以编译出程序来,但是真正有用的程序有哪个是这么拖出来的?很多从Windows平台入门学编程的人,编了好几年程序,还是只知道编完程序点一个按钮就可以跑了,把几个源文件拖到一个项目里就可以编译到一起了,如果有更复杂的需求他们就傻眼了,因为他们脑子里只有按钮、菜单的概念,根本没有编译器、链接器、Makefile的概念,甚至连命令行都没用过,然而这些都是初学编程就应该建立起来的基本概念。另一方面,编译器、链接器和C语言的语法有密切的关系,不了解编译器、链接器的工作原理,也不可能真正掌握C的语法。所以,IDE并没有帮助你学习,而是阻碍了你学习,本来要学好C编程只要把语法和编译命令学会就行了,现在有了IDE,除了学会语法和编译命令,你还得弄清楚编译命令和IDE是怎么集成的,这才算学明白了,本来就很复杂的学习任务被IDE搞得更加复杂了。Linux用户的使用习惯从来都是以敲命令为主,以鼠标操作为辅,从学编程的第一天起就要敲命令编译程序,等到你把这些基本概念都搞清楚了,你觉得哪个IDE好用你再去用,不过到那时候你可能会更喜欢vi或emacs而不是IDE了。
Windows 系统相对更加强调图形化一些,图形化优势在于直观。但也容易让人迷惑,总是贪图着简单方便,不求甚解,大概会更加地趋于平庸。Unix系列的 Linux 强调效率,在命令行方面做的是非常地完善好用。
关于命令行和图形化哪个好的问题,需要结合具体的应用场景来看待,在不同的场景中它们各有各的利弊。
私以为图形界面比较适合做一些强调直观的工作,比如说多媒体编辑,类似PS、视频、音频编辑等。类似“让照片里面的妹纸脸上的痘痘消失”这样子的需求,要做这个工作,你总不可能用命令行输入一个个像素去调吧。
对于编程开发这样大部分时间需要高度精确、且经常遇到重复操作的工作来说,命令行更加适合一些。修改命令参数,再执行一次命令,与每次都要弹个窗口修改,然后点击确定按钮这一连串操作相比,显然要简单舒服许多。
引用一则著名的文章:《无名师的GUI论》 (原文:Master Foo Discourses on the Graphical User Interface )
一晚,无名师和Nubi参加一个程序员的探讨会。有个程序员问Nubi和他的老师来自哪所学校。当得知他们是Unix大道的追随者时,程序员颇为不屑。 “Unix命令行工具太粗糙太落后”,他讥讽道。“现代的、设计得当的操作系统可以在图形用户界面中做任何事情。” 无名师一言不发,只是指着月亮。旁边的一条狗对着他的手狂吠。 “我不明白。”程序员说。 无名师依然缄默,指着一幅佛祖像,然后又指着一扇窗。 “你想说什么?”程序员问。 无名师指着程序员的头,接着指着一块大石。 “请把话说清楚!”程序员要求道。 无名师深深蹙眉,轻拍程序员的鼻子两下,把他扔到旁边的垃圾箱中。 程序员试图从垃圾堆挣扎出来之时,那条狗跑过来在他身上便溺。 此时,程序员眼中一亮。
或许有人会说,大家都在用 Windows,VC,我为什么要折腾这些?放眼望去,计算机在不断地高速发展变化之中,而学院的课程总是在“照顾”着大多数人,如果你仅仅只是跟着学院安排的课程,按部就班地学,那是远远不够的。计算机科学是一门自主性非常强的学科。需要锻炼自己的自学能力。所以也希望大家可以多多折腾,互相多多交流,多多进步。
遇到困难的时候,我们有互联网,还有一群热爱折腾的小伙伴们和热心的老师,所以放心大胆地去干吧!
如果有什么疑问的话,希望可以尽快提出。
本文在 0xFFFF 讨论请戳:https://0xffff.one/d/58