C语言---面试之预处理篇

Posted 今天天气眞好

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言---面试之预处理篇相关的知识,希望对你有一定的参考价值。

预处理有文件包含、宏定义、条件编译,其中最重要的是宏定义,通常考察宏定义的语法、宏替换和与函数的区别。

1.宏定义是在编译的哪个阶段被处理的?
答案:编译预处理阶段
解读:编译预处理包含:头文件包含,宏替换,条件编译,去除注释,添加行号

2.C语言编译过程中,关键字volatile和extern分别在哪个阶段起作用?
答案:volatile在编译阶段,extern在链接阶段
解读:C语言编译过程分为:预处理、编译、汇编、链接

3.写一个”标准“宏MIN,这个宏输入两个参数,返回较小的那一个
答案:#define MIN(A,B) (A)<=(B)?(A):(B)
解读:注意这个题目要用到三目运算符,在宏中要小心的把参数,用括号括起来,并且整个宏也要用括号括起来,防止替换的时候出现错误

4.已知数组table,用宏求数组的大小
答案:#define COUNT(table) (sizeof(table)/sizeof(table[0]))

5.带参宏和函数的区别
解读:(1)带参宏只是在编译预处理阶段进行简单的字符替换,而函数是在运行时候进行调用和返回
(2)宏替换不占用运行时间,只占用编译时间,而函数调用则占用运行时间(分配单元、保存现场、值传递、返回)
(3)带参宏在处理时候不分配内存,而函数调用会临时分配内存
(4)宏不存在类型问题,宏名无类型,他的参数也是无类型的;而函数中的实参和形参都要定义类型,二者的类型要求一致
(5)使用宏定义次数多时,宏替换后源程序会变长;而函数调用不会使源程序变长

6.“在C语言中,凡是以#开头的都是预处理命令,同时预处理命令都是以#开头的”,这句话正确吗?
答案:正确

7.预处理标识#error的作用是什么?
答案:编译程序时候,只要遇到#error就会跳出一个编译错误
解读:当程序较大时,往往有些宏定义是在外部指定的
(如:Makefile),或者是在系统头文件中指定的,当你不太确定是否定义了XXX时候,可以写以下代码:

#ifdef
#error "XXX has been define"
#else
...
#endif

这样,如果编译出现错误,输出了XXX has been define,表明宏XXX已经定义了

8.用预处理指令#define声明一个常数,用以表示1年中有多少秒(忽略闰年问题)
答案:#define SECONDS_PER_YEAR(606024*365)UL
解读:注意表达式将使得一个16位机的整型数溢出,因此采用UL无符号长整型,告诉编译器这个常数是一个无符号的长整型数

9.预处理,编译过程中最先做的是什么?
答案:编译#开头的指令

10.何时需要预编译?
总是经常使用但是不经常改动的大型代码

11.C语言中#与##的区别以及作用?
#:把宏参数变成一个字符串
##:把两个宏参数连接到一起(只能是两个)

12.如何避免头文件被重复包含?
答案:

#ifndef
#define
#endif

解读:如果不存在,会执行#define进行定义,如果存在,也不会重复包含

以上是关于C语言---面试之预处理篇的主要内容,如果未能解决你的问题,请参考以下文章

面向面试编程代码片段之GC

面试常见问答之C++:1 - 10

Python面试重点(基础篇)

Python面试重点(基础篇)

C语言面试题总结

面试宝典2之多线程网络篇