在标准c语言的任何实现中,存在两个不同的环境
1.翻译环境:源代码->机器指令(二进制)
2.执行环境用于实际执行代码。
在windows环境:
源文件->编译器->目标文件->链接器<-链接库。
编译的三个过程:
1.预编译(预处理):相当于把头文件中的代码释放,清理掉源文件的注释,对define符号进行替换,属于文本操作,此过程后生成test.i。防止头文件被多次释放造成冗余,可以用条件编译语句:
#ifndef<头文件>
2.编译:对text.i处理得到text.s,将c语言代码通过语法分析,词法分析,符号汇总,语义分析等过程转化成汇编语言。
3.汇编:对text.s处理生成text.o,形成符号表(变量,地址)。
链接:
1.合并段表:对符号表进行检查,保留有用的变量和地址。
2.对符号表进行合并和重定位。
运行环境:
1.程序载入内存,在有操作系统的环境中,一般由操作系统完成。在独立的环境中,程序由手工按拍,可能是通过可执行代码置入只读内存来完成。
2.程序执行,调用main。
3.执行程序,创建函数栈帧……
4.终止程序,正常终止main,返回值为0(也就是平常程序写的return 0),也可能意外终止。
预处理详解:
LINE,DATE,TIME,STDC
这些都是预处理命令,如果编译器遵循标准c的规定,那么STDC的值则是1,否则是未定义的。
预处理符号:_FILE_ 进行编译的源文件。
printf(“FILE:%s”,_FILE_);
要注意当vs与gcc的结果不一致时,以gcc为主,因为gcc遵循标准c规定。
“\”是续行符,当代码一行放不下时,可以使用。
宏:
有参数的define为宏。
如:define ADD(X) X+X
#在宏中的运用:
#include<stdio.h>
#define print(A) printf(#A"值为%d ",A);
int main()
{
int a = 5;
print(a);
printf("\n");
int b = 10;
printf("\n");
print(b);
return 0;
}
结果如下:
宏与函数的比较:
优点:
宏在程序规模和速度方面更胜一筹。
不足:
1.使用宏时,定义的代码会插入程序中,除非宏比较短,否则会大幅增加函数的长度。
2.宏是不可以调试的。
3.因为宏是没有类型的,所以相对函数来说不够严谨。
4.宏的运算符优先问题,可能会导致出错。
一般的习惯来说,宏是全大写,函数是部分大写或者是首字母大写。
#unfed是用来取消一个宏定义。
条件编译:
#ifdef (定义)
#endif
是配合使用的,不可缺少。有点像函数中的条件选择。
相对的,还有:
#ifdef(定义)
#elif
#endif
相当于#endif是条件编译的结束符。
常用的等价编译语句:
#ifdefined <=>#ifdef.
#ifndef<=>#if!defined.