面试问题1
#include <stdio.h>
#define PRINT_HELLO(i, times) do \
{ \
if (i++ < times) \
{ \
printf("嵌入式客栈\n"); \
continue; \
} \
}while(1)
int main()
{
PRINT_HELLO(0, 3);
return 0;
}
答案:D
解析:PRINT_HELLO宏在预处理器时被扩展。宏展开后,if表达式变为:if(0 ++ <3)。0是一个常数,常数如何自增呢?,因此应用增量运算符会产生编译时错误。
面试问题2
#include <stdio.h>
#if A == 3
#define B 3
#else
#define B 5
#endif
int main()
{
printf("%d", B);
return 0;
}
答案:B
解析:乍一看,输出似乎是编译时错误,因为尚未定义宏A,所以A是不等于3的,所以会将B定义为5。你如不信,也可以用上面的办法gcc -E hello.c -o hello.i来验证,或者编译运行一遍。
面试问题3
#include <stdio.h>
#define X 3
#if !X
printf("嵌入式");
#else
printf("客栈");
#endif
int main()
{
return 0;
}
答案:C 编译错误
解析:程序编译三部曲:预处理、汇编、链接,那么在预处理时,上述代码就变成下面这样:
#这里还有stdio.h的包含内容
printf("客栈");
int main()
{
return 0;
}
printf在main外面被调用了,所以编译会出错。
面试问题4
#include <stdio.h>
#define IS_EQUAL(X, Y) X == Y
int main()
{
#if IS_EQUAL(X, 0)
printf("嵌入式");
#else
printf("客栈");
#endif
return 0;
}
答案:A
解析:条件宏#if IS_EQUAL(X,0)扩展为#if X ==0。预处理结束后,所有未定义的宏均使用默认值0初始化。
面试问题5
#include <stdio.h>
#define SQUARE(x) x*x
int main()
{
int x;
x = 2000/SQUARE(10);
printf("%d", x);
return 0;
}
答案:B
解析:预处理器用10*10替换SQUARE(10),表达式变为 x = 2000/10 * 10,x的值计算为2000。如前所说,应定义如下:
#define SQUARE(x) ((x)*(x))
面试问题6
# include <stdio.h>
# define scanf "%s Embedded Inn "
int main()
{
printf(scanf, scanf);
return 0;
}
答案:D
解析:在编译的预处理阶段之后,printf语句将变为。
printf(“%s Embedded Inn”,“%s Embedded Inn”);
面试问题7
#include <stdio.h>
#define STR "嵌入式"
int main()
{
printf("%s",STR);
#define STR "客栈"
printf("%s",STR);
return 0;
}
答案:B
解析:如果重新定义预处理程序指令,则预处理器不会给出任何错误,它可能会发出警告。预处理器在使用之前获取新值,并将其替换。
面试问题8
#include<stdio.h>
#define ADHESION(x,y) x##y
int main()
{
int var1 = 100;
printf("%d", ADHESION(var,1));
return 0;
}
答案:A
解析:运算符##称为“令牌粘贴(Token-Pasting)”或“合并(Merge)”运算符。它将两个符合合并为一个。因此在预处理之后,printf变为。
printf("%d", var1);
面试问题9
#include <stdio.h>
#define MAX 6666.6f
int main()
{
float MAX = 666.6;
printf("%f ", MAX);
return 0;
}
答案:C
解析:展开一看便知。
int main()
{
float 6666.6 = 666.6; //常数不可为左值
printf("%d ", 6666.6);
return 0;
}
面试问题10
#include <stdio.h>
#define macro(n, a, i, m) m##a##i##n
#define MAIN macro(n, a, i, m)
int MAIN()
{
printf("嵌入式客栈");
return 0;
}
答案:B
解析:不注意可能会选A,认为将MAIN敲成大写了,其实仔细一看,通过前面两个宏以及粘连操作符##将MAIN替换成main,所以没有问题,这个题目比较骚,主要考察细心以及粘连操作符。
总结一下
本文总结了宏的基本工作原理,以及10个比较典型的面试问题,相信对于宏理解不深的盆友会有些许帮助。
本文辛苦原创,如喜欢请点赞/在看/分享支持,不胜感激!
本文分享自微信公众号 - 嵌入式客栈(embInn)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。