嵌入式面试总结

最近面了很多公司,总结一下最近遇到的题目,很多高频出现,后来看了一下,这些都是很经典的题目,写一个笔记,日后复习,不定期更新

宏定义问题

1、写一个标准宏MIN,输入两个参数返回较小的一个

个人理解:

      这个题考的事使用宏定义函数的基础,外加三目运算符的考察

我的解答:

    #define MIN(a,b)((a)>=(b)?(b):(a))

2、使用宏定义 定义一个常数,一年有多少秒(忽略闰年)

个人理解:

    这个题考察宏定义基本用法,还有普通平台下数据类型长度的问题在32位的设备上int是 4个byte 8位和16位是2个byte,为了兼容各平台最好使用unsigned long,以便在使用的时候不会出问题

 

我的解答:
    #define SECOND_YEAR   (60*60*24*360ul) 

(ps. 有一种写法是

#define SECOND_YEAR (60*60*24*360)ul

,这种我没有验证,但是再16位或者8位的系统上这个数值已经大于0xffff,可能出现超出的情况,保守起见用上面的方法 )

3、宏定义#和##的区别

个人理解:

    我觉得这个可能会很多人不知道后面那个,至少我是这样的,根本没有使用过##,不过在apm的源码中看到过很多次,之前没注意,现在重新温习一下

我的解答:

 

#define a_printf(x) printf( "token " #x" = %d\n ", token##x ) 
所以a_printf(1);就是相当于 printf("token 1 = %d\n",token1);

还有一个#的例子很经典

 

#define MONCK(ARGTERM) /
    printf("The term " #ARGTERM " is a string/n")
MONCK(A to B);
输出:
The term A to B is a string

4、#error、#warning有什么用?

个人理解:

    这个可能非常简单,但是很少人用,在apm源码中非常常用,因为apm要跨五六个平台,编译的时候要做出提示或者是报错

我的解答:

#define NIU_BI
#ifdef NIU_BI
#error "there is a niubi problem"
#else
#warning "ni niubi,mei mao bing"
#endif

预编译的时候会进行一个处理,如果定义了NIU_BI,那么编译器将会报错,输出后面的字符串,如果没有的话,编译器将会输出一个警告,但并不影响编译

5、如何使用可变参数的宏

 

个人理解:

熟悉Java的同学对这个再熟悉不过了,有点类似。确实可变参数宏在嵌入式编程中是一大利器

网络解答:

可变参数可以用三个点(...)来表示,,可以用__VA_ARGS__来展开,如:

#define err(...) fprintf(stderr,__VA_ARGS__)
err("%s %d/n","The error code: ",48);

一般,我们可以这样打印错误信息:

 

fprintf(stderr,"%s %d/n","The error code ",48);

但想要另外输出其它信息,我们可以这样定义一个可变参数的宏,例如:

#define errout(a,b,...) /
    fprintf(stderr,"File %s     Line %d/n",a,b); /
    fprintf(stderr,__VA_ARGS__)

那么我们就可以这样使用这个宏:

errout(__FILE__,__LINE__,"Unexpected termination/n");

 

因为__VA_ARGS__在fprintf中的内部实现使用了逗号来作分割符,所以必须要求至少有一个参数,如果想使__VA_ARGS__为空,可以这样使用:

fprintf(stderr, ##__VA_ARGS__);

6、为什么要使用宏定义,有哪些注意事项?

因为 宏的效率高,不需要压栈 和出栈,而且可以节省代码
使用宏不能使用递归,宏只是进行简单替换,
定义的时候最好加上括号,确定优先级,反之在预编译的时候出现替换
造成优先级变化的问题。C语言里没有模板,而c语言的宏恰恰相当于C++的模板,
虽然宏很好用,但是还是不要过于使用宏,最好只是用于一些函数比较难实现的场景。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值