Visual Studio系列开发工具支持中文,在编译器设置方面很友好,具备提示功能。本节将通过一个向控制台输出“Hello, world!”的程序为读者演示如何使用Visual Studio 2019工具开发C语言应用程序,具体实现步骤如下。
1、新建项目
(1)打开Visual Studio2019,单击【继续但无需代码】选项,如图1-9所示。进入Visual Studio2019主界面后,在菜单栏依次点击【文件】→【新建】→【项目】,在弹出界面选择空项目选项,如图1所示。
(2)在图1中,选择【空项目】后,单击【下一步】按钮,进入配置项目界面,如图2所示。
(3)在图2中,设置项目名称、选择项目存储路径,并勾选“将项目解决方案和项目放在同一个目录中”选项。配置完成之后,单击【创建】按钮完成项目创建,进入Visual Studio 2019主界面如图3所示。
2、编写程序代码
(1)在图3所示界面中,选择源文件目录右击à【添加】à【新建项】,弹出添加新项对话框,如图4所示。
(2)在图4中,将文件命名为“helloworld.c”,单击【添加】按钮,helloworld.c源文件创建成功。双击打开helloworld.c文件,在文件空白区域编写代码,如图5所示。
1#include 2intmain()3{4//使用系统提供的标准输出,在控制台显示信息5printf("Hello, world!\n");6return0;7}
3、编译运行程序
单击图5菜单栏的【调试】→【开始运行(不调试)】运行程序,或单击菜单栏【本地Windows调试器】按钮运行程序。程序运行后,会弹出运行结果的命令行窗口,该窗口会输出程序的运行结果,如图6所示。
4、代码分析
Helloworld.c程序共包含7行代码,各行代码的功能与含义分别如下:
● 第1行代码的作用是进行相关的预处理操作。其中字符“#”是预处理标志,include后面跟着一对尖括号,表示头文件在尖括号内读入。stdio.h就是标准输入输出头文件,因为第5行用到了标准库中的printf()输出函数,printf()函数定义在该头文件中,所以程序需要包含此头文件。
● 第2行代码声明了一个main()函数,该函数是程序的入口,程序运行从main()函数开始执行。main()函数前面的int表示该函数的返回值类型是整型。第3~7行代码,“{}”中的内容是函数体,程序的相关操作都要写在函数体中,在“{}”内的语句被称为语句块。
● 第4行是程序注释,注释使用“//”表示,从“//”开始到该行结束部分属于注释部分,注释不参与程序编译过程。
● 第5行代码调用了格式化输出函数printf(),该函数用于输出一行信息,可以简单理解为向控制台输出文字或符号等。printf()括号中的内容称为函数的参数,括号内可以看到输出的字符串“Hello, world!\n”,其中“\n”表示换行操作。
● 第6行代码中return语句的作用是将函数的执行结果返回,后面紧跟着函数的返回值,如果程序的返回值是0,表示正常退出。
在C语言程序中,以分号“;”为结束标记的代码都可称为语句,如helloworld程序中的第5行、第6行代码都是语句。
C程序编译过程
在前面小节提到早期的编程使用汇编进行编程,汇编程序难于移植,使得开发效率低下。C语言的出现使得编程关注程序逻辑本身,提高了编程的效率。那么计算机是如何理解C语言代码,进而执行程序,给出运行结果的呢?其中编译器的作用就是将编写的C源程序翻译成机器能够执行的指令和数据,机器能够直接执行的指令和数据称为可执行代码。C语言从源代码到可执行代码需要经过预处理、编译、汇编和链接四个步骤,如图1所示。
下面以“HelloWord.c”程序为例,并结合图1讲解C语言程序的执行过程。
(1)预处理
预处理主要处理代码中以“#”开头的预处理语句(预处理语句将在第10章讲解),预处理完成后,会生成*.i文件。预处理操作具体包括:
● 展开所有宏定义(#define),将宏替换为它定义的值;
● 处理所有条件编译指令(#ifdef、#ifndef、#endif等)。
● 处理文件包含语句(#include),将包含的文件直接插入到语句所在处。
需要注意的是,代码中的编译器指令(#pragma)会被保留。除此之外,预处理还会进行以下操作:
● 删除所有注释;
● 添加行号和文件标识,以便在调试和编译出错时快速定位到错误所在行。
(2)编译
编译过程是最复杂的过程,需要进行词法分析、语法分析、语义分析、优化处理等工作,最终将预处理文件“.i”生成汇编文件“.s”。编译的过程是优化过程,包括中间代码优化和针对目标代码生成优化。
(3)汇编
汇编操作指将生成的汇编文件.s翻译成计算机能够执行的指令,称为目标文件或者中间文件。在Linux系统中的二进制文件是“*.o”文件,Windows系统中是“.obj”文件,通常汇编后的文件包含了代码段和数据段。
(4)链接
生成二进制文件后,文件尚不能运行,若想运行文件,需要将二进制文件与代码中用到库文件进行绑定,这个过程称为链接。链接的主要工作就处理程序各个模块之间的关系,完成地址分配、空间分配、地址绑定等操作,链接操作完成后将生成可执行文件。链接过可以分为静态库链接和动态库链接。
静态库在Linux中是“.a”文件,Windows下是“.lib”文件。这些静态库文件本质上是一组目标文件的集合,静态库链接指的是在程序链接过程中将包含该函数功能的库文件全部链接到目标文件中。程序在编译完成后的可执行程序无需静态库支持,但静态链接带来程序开发效率高的同时也存在着内从空间和模块更新难等问题的出现。
动态库在Linux中是“.so”文件,也称为共享库,Windows下是“.dll”文件。动态库链接指的是在程序运行时只对需要的目标文件进行链接,因此程序在运行过程中离不开动态库文件,动态库解决了静态库资源的浪费并且实现了代码共享、隐藏了实现细节、便于升级维护等特点。
多学一招:C语言编译器
C语言编译器在编译源码过程中会进行词法分析、语法分析、语义分析、中间语言生成、目标代码生成与优化、链接库文件(动态库或静态库)处理。不同的编译器对程序的优化处理不一样,本书中使用的MSVC编译器是微软公司专用于Visual Studio系列的编译器CL,其他常见的C语言编译器有GCC、MinGW、Clang、Cygwin。读者可查找相关资料使用编译器指令将源文件按照编译过程生成最终的可执行文件,对编译过程有更详细的了解。
最适合自学的C语言基础
配套资料(+企鹅:49.89.1386.8)