下乡扫盲C语言 Chapter 1

 

 

  这一章我们不讲太深的东西,我只会解释某些基本概念,这些基础知识将对读者的日后学习有很大帮助。

  实际上,我们要从VC6.0开头。

 

0: VC 6.0?

  我有理由相信,绝大多数读者的第一次上机实践,第一个helloworld程序,都是在VC 6.0上进行的。国内大部分教材,老师的课件,也以其VC 6.0作为标准。很多学生会在很长的时间里,坚持使用这个来自遥远的1998年,早已被微软遗忘的IDE。我将借用VC 6.0解释一些基本概念。

  首先,VC 6.0是什么呢?VC 代表 Microsoft Visual C++,是Microsoft公司推出的以C++语言为基础的开发Windows环境程序,面向对象的可视化集成编程系统。这段黑体字指出两点,第一,VC是一个集成开发环境(Integrated Development Environment),IDE就是一个集成  代码编辑器,编译器,调试器,可视化工具  等一系列编程工具的软件,不妨想象这是一个工具箱,里面的工具应有尽有。第二,VC并不是为开发C语言应用设计的,甚至也不是为开发C++语言应用而设计的,它是为"以C++语言为基础的开发Windows环境程序"而设计的软件。

  VC只是一个兼容了ANIS C(C89)的工具,然而不幸的是,它既不适合用来开发一个仅使用C语言的应用,也不适合用来开发Windows程序。我们现在可以提一句,"6.0"这个版本号来自于VC 6.0包含的"MFC 6.0"(MFC: Microsoft Foundation classes),这是微软过去用C++设计的,用来开发Windows程序的一些库。不幸的是这个库如今几乎被开发者们抛弃了,现在有很多比它更新,更好的东西,何必浪费生命在MFC上呢。

  如今已经有了很多更新,更好的IDE,VC 6.0是彻底的过时了。

  如果电脑够好,请换VS2017(很吃配置),VS支持ANSI C,并提供了一些扩展的函数,如果追求"纯粹"的C语言,也可以选装Clang插件。否则可以用codeblock+gcc(具体安装,配置请自行搜索资料学习)。至于linux用户,再见了您那。

 

1: IDE 是啥?代码编辑器?编译器?

  想理解为什么编写一个程序需要这么多软件,读者必须回到遥远的二十世纪,体验一下如何过去的程序员是如何编写程序的。接下来我将宣布一个好消息和一个坏消息。坏消息是,截止这篇博客发表的时间,人类还没能成功地设计出时间机器。好消息是,我们还有linux。为了演示,笔者使用VMware Workstation安装了一个Ubuntu虚拟机(Ubuntu 是 Linux的一种"发行版",具体细节过于复杂,但可以暂时认为这就是Linux),并将在控制台模式演示如何只使用键盘来编写,编译,调试一个helloworld程序(Ubuntu实际上已经有了图形界面,但我们只用控制台模式做演示)。

  我们将使用三种工具,这三种工具在大部分Linux系统中都是预装好的

  1. vi 代码编辑器。就像Windows系统中的"记事本"程序,Linux系统也为我们提供了一种编辑单纯文本的软件,通常就是vi。我们需要用这样的程序来编写代码。

  2.GCC 编译器。 这个程序处理我们编写的代码,通过编译和链接,把原本只是文本的代码转换为一个可执行文件。只有可执行文件才能运行。

  3.GDB 调试器。 有时我们希望能按步执行程序,查看某些变量是否符合预期。这时我们就用到调试器,调试器可以让我们调试程序的运行,检测错误,检测代码的效率。

  

第一步,登录系统。

 

                                                                                      

第二步,我们找一个文件夹来放我们的文件,我们登录到linux控制台时,控制台的工作目录是当前用户的根目录。使用 ls(list) 指令,列出当前用户目录下的文件和文件夹。

                        

第三步,用 cd 指令进入文件夹(没有截到图),这个文件夹是随便选的。

    cr@ubuntu:~$ cd Templates

第四步,用 touch 指令新建一个C语言源文件 helloworld.c。然后用 vi 来编辑这个新建的文本。(事实是,直接使用第二个命令,也可以新建一个文本的)

                        

第五步, 编写代码并保存。

                        

第六步,用gcc编译,注意这里使用了两个可选的参数 ,'-g' 表示应生成调试信息,-o 后紧跟 helloworld 表示输出文件名为 helloworld(注意没有后缀名。若不使用 '-o',输出文件名为默认的a.out)

第七步,编译完成,没有错误信息。紧跟着,我们执行编译出的helloworld,控制台输出"helloworld",程序无误。

                        

第八步,我们希望能单步运行程序,以调试和查看一些信息。我们使用gdb来调试helloworld

                        

第九步,使用 list 命令,查看源代码。我们在第三行设置一个断点,使用 run 命令来执行程序到第一个断点。随后使用 next 命令按行执行,直到程序结束。

                        

                        

                        

  任何一个读到这里的读者都应该体会到了,在过去没有图形界面时,程序员们想要编写一个程序是怎样地困难。他们不得不用一个程序来编写代码(代码编辑器), 一个程序来编译代码(编译器), 一个程序来调试编译后的程序(调试器)。如果他们想要一个图表来看一看程序运行过程中,对内存,CPU的占用,他们就不得不额外写一个程序,在控制台用ASCII 字符来打印图表。(可视化工具)。幸运的是,如今我们有了IDE,在大部分情况下,我们只要从头到尾地使用IDE就可以了。但不幸的是,在特定环境下IDE反而不适用,例如,VS会在我们编写程序时悄悄进行编译,以提供实时的代码提示,错误提示。然而当我们编写的代码量大到惊人的地步(某些商业软件的源码可远超数十MB),这时直接在VS里改动代码,VS的编译就会占用极大内存和CPU时间。所以,这时就需要先好编写代码,再编译调试。我建议各位读者不要只满足于一个顺手的IDE,最好对其它工具也了解一些。

 

 2.代码是怎么变成程序的

  代码只是单纯的文字而已。如果我们打开一个txt,写一个helloworld进去,它能执行吗?不能,因为它只是一个文本,我们一向说,'.c'是源文件,'.h'是头文件。但实际上,后缀名无关紧要,在windows系统中,后缀名只是向试图打开这个文件的程序说明这个文件的类型。但事实是,你在VC 6.0里新建的 '.c',实际上就是一个文本文件,它和'.txt'一点区别都没有。(虽然我这么说,但请读者不要试图直接在txt或者Microsoft Word里写代码,这里实际上还有编码格式的问题)。我们可以用一句非常简单的话回答标题的问题,代码进到编译器里,出来就变成了程序。

  但编译器做了什么呢?它做了两件事,一是编译,而是链接。

  编译的部分是,编译器把你编写的每一个 '.c' 编译成一个 '.o'(中间文件),将能处理的代码都翻译成汇编代码,然后在某个恰当的时候,编译器会将汇编代码再进行一次汇编,生成二进制文件。但特别的是,如果一个函数不是在某个源文件中定义的,却在这个源文件使用了,编译器就会去查看这个源文件的头文件是否包含了这个函数的声明,如果找到了,就在此做一个标记。稍后,是链接的部分,编译器试图将每个中间文件与他们依赖的其它中间文件链接在一起,并正确改写之前做标记的地方,使整个程序中,每一个变量,每一个函数的声明和定义都是完整的,每一次调用函数都符合声明,否则就会编译失败。

  一旦程序的链接完成,编译器就把它打包成一个可执行文件,在Windows中,你得到一个后缀名为'.exe'的PE文件(Portable Executable)。而在Linux中,后缀名是没有意义的,可选择的,所以你得到一个ELF文件(Executable and Linkable File)。操作系统会知道,如何适当地把这个exe加载到内存中去,执行二进制的代码,如果没有对程序做任何的加密和压缩,一般情况下,二进制代码和汇编指令是可以很简单地相互转换,所以我们可以认为在内存中运行的,就是一个汇编程序。所以,如果一个学习C语言的程序员能掌握一些汇编知识,对于程序的编译,调试,优化都能有更好的掌握。

 

这一章就到这里,我希望读者读完这篇文章能对于一些概念有较生动的理解

1. IDE

2. 编译器

3. 调试器

4. 编译,链接

 

posted @ 2018-04-15 19:42  TCR  阅读(139)  评论(0编辑  收藏  举报