C语言翻译环境作业
一
答案:C
解析:
A 预处理阶段主要处理#开头的指令,主要是宏展开和头文件包含,不会检查函数函数是否定义。
预处理相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有头文件(都已经被展开了)、宏定义(都已经替换了),没有条件编译指令(该屏蔽的都屏蔽掉了),没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内容上有所不同
B 编译阶段会将预处理后的源代码逐个翻译成目标文件,检查当前源文件的语法错误和类型匹配等,如果函数被声明(例如通过头文件),编译器会假设该函数在其他地方定义,并生成一个符号引用(symbol reference),不会报未定义错误。
将预处理完的文件逐一进行一系列词法分析、语法分析、语义分析及优化后,产生相应的汇编代码文件。编译是针对单个文件编译的,只校验本文件的语法是否有问题,不负责寻找实体。
C 链接器将多个目标文件以及库文件合并成一个可执行程序。它的主要任务是解析符号引用(如函数调用),找到每个符号的实际定义地址。如果链接器在所有目标文件和库中都找不到某个被调用函数的定义,就会报错:“undefined reference to 函数名”。这就是发现“被调用的函数未定义”的阶段
通过链接器将一个个目标文件(或许还会有库文件)链接在一起生成一个完整的可执行程序。 链接程序的主要工作就是将有关的目标文件彼此相连接,也就是将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。在此过程中会发现被调用的函数未被定义。需要注意的是,链接阶段只会链接调用了的函数/全局变量,如果存在一个不存在实体的声明(函数声明、全局变量的外部声明),但没有被调用,依然是可以正常编译执行的。
D 程序已经生成并运行,此时发现的是运行时错误(如段错误、除零错误),而不是未定义函数错误。
二
答案:A
解析:
编译的上一步就是预处理,生成.i文件
三
答案:B
解析:
预处理的#define是查找替换,所以替换过后的语句是“int*a,b;”,其中b只是一个int变量,如果要让b也是指针,必须写成“int *a, *b;”。而typedef没有这个问题,c、d都是指针。故选B。
四
答案:D
解析:
程序运行结束就停止了,还可以通过ctr+c等方式终止程序。
五
答案:D
解析:
前三个是常用宏,分别是:打印所在文件、打印编译时间、打印编译日期。除此之外,还有__LINE__(行号)、__FUNCTION__(函数名)等宏,而__MAIN__并不存在,故选D。
六
答案:D
解析:
#define执行查找替换,#if可以区分是否编译,#undef可以反定义,也就是取消#define宏定义的东西,#end并没有这玩意,只有#endif,故选D。
七
答案:D
解析:
Y(5+1)经过替换后是((N+2)*5+1),其中N是4,所以结果是31,2 * (4 + 31)结果为70,选D。
八
答案:B
解析:
宏C预处理后的代码是:2+2*3+3,即2+6+3,等于11,选B。