运行c
程序的过程
编译
编译器可以将源代码转换成机器语言,在编译过程中,会找出错误并报告。这个阶段的输入是在编辑期间产生的文件,常称为源文件。
编译器能找出程序中很多无效的和无法识别的错误,包括结构错误,例如程序的某个部分永远不会执行。编译器输出的结构叫作对象代码,存放它们的文件叫作对象文件。在Linux
中这些文件的扩展名通常是.o
,在Windows
下面这些文件的扩展名通常是.obj
。如果编译成功就会生成一个文件,它与源文件同名。但扩展名为.o
或者.obj
。
其实我们在上一节编写第一个C
语言程序的时候,使用的gcc -o 1-1 1-1.c
这条命令既包含了编译也包含了链接,所以直接生成了可执行文件1-1
。
在Linux
下编译是在源代码文件所在目录输入以下命令(假如源代码文件是上节课的 1-1.c):
gcc -c 1-1.c
这时源文件所在的目录将会生成1-1.o
的文件。
链接
链接器将源代码文件中由编译器产生的各种对象模块组合起来,再从C
语言提供的程序库中添加必要的代码模块,将它们组合成一个可执行文件。链接器也可以检测和报告错误,例如程序中引用了一个根本不存在的库组件。链接一旦成功,就会生成可执行文件,在Windows
下面可执行文件的扩展名是.exe
,在Linux
下面,可执行文件没有扩展名,但它的文件类型是可执行的。
在编译生成 .o
文件的基础上我们将会输入以下命令(以编译生成1-1.o
为例):
gcc -o 1-1 1-1.o
这时1-1.o
所在的目录将会生成1-1
可执行文件。
多数情况下,我们是通过gcc -o 1-1 1-1.c
一次性完成编译和链接。
执行
执行阶段就是成功完成了前述的三个过程后,运行程序。但是这个阶段可能会出现各种错误,包括输出错误,计算机什么也不做哦,甚至是计算机崩溃。无论如何,都需要我们返回编辑阶段,检查并修改源代码。相信大家都还记得上一节课的执行命令,在文件所在目录执行:
./1-1
创建C
程序的各个过程:
C语言的简单结构
预处理指令
1-1.c
的第一行代码如下:
严格地说,它不是可执行程序的一部分,但它很重要,事实上程序没有它是不能执行的。符号#
表示这是一个预处理指令,告诉编译器在编译源代码之前,要先执行一些操作。编译器在编译过程开始之前的预处理阶段会处理这些指令。预处理指令的类型相当多,大多放于程序源文件的开头。
在这个例子中,编译器要将stdio.h
文件的内容包含进来,这个文件被称为头文件,因为通常放在程序的开头处。在本例中,头文件定义了 C 标准库中一些函数的信息,本例要用到标准库中的printf()
函数,所以必须包含 stdio.h
头文件。stdio
是“ standard input & output ”的缩写,包含了编译器理解printf()
以及其它输入 / 输出函数所需要的信息。C
语言所有头文件的扩展名都是.h
。在以后的学习过程中大家会看到很多其它的预处理指令。
main()函数
int main()
{
printf("Hello World!");
return 0;
}
main()
函数是“主函数”。每个C
程序都由一个或多个函数组成,但每个C
程序都必须有一个main()
函数——因为每个程序总是从这个函数开始执行。
程序的几乎全部工作都是由各个函数分别完成的,函数是C
程序的基本单位,在设计良好的程序中,每个函数都用来实现一个或多个特定的功能。
一个C
语言程序由一个或者多个函数组成,其中必须包含一个main()
函数(且只能有一个main()
函数)。
一个函数包括两个部分:
一是 函数首部
即函数的第一行:
int main()
二是 函数体
即函数首部下面的花括号内的部分:
{
}
printf()
函数
printf()
是C
编译系统提供的函数库中的输出函数。printf()
函数中双撇号内的字符串“Hello World!”按照原样输出,每个语句最后都有一个分号,表示语句结束。