一道C面试题的思考

简介: C语言真的是学无止境的感觉,大部分同学大学都会开设C语言课程。很多人把C语言二级过了就感觉入门了;对于那些在做嵌入式开发的工程师,几乎每天都要接触C语言,很多人会感觉自己C语言学得很溜了。那好,咱们用一道C语言面试题来测试一下。

一、前言

C语言真的是学无止境的感觉,大部分同学大学都会开设C语言课程。很多人把C语言二级过了就感觉入门了;对于那些在做嵌入式开发的工程师,几乎每天都要接触C语言,很多人会感觉自己C语言学得很溜了。那好,咱们用一道C语言面试题来测试一下。

二、面试题

首先给出题目:
定义一个宏,求两个数中的最大数

OK,很多人应该能很快写出

#define  MAX(x,y)  x > y ? x : y

接下来我们写一个测试程序

#define MAX(x,y) x > y ? x : y
int main(void)
{
    printf("max=%d",MAX(1,3)); //测试通过
    printf("max=%d",MAX(4,1));//测试通过
    printf("max=%d",MAX(2,2));//测试通过
    printf("max=%d",MAX(3!=3,1!=2)); //好像不是我们要的结果
    return 0;
}

我们会发现第四个测试不是我们的要结果了。这是因为宏展开后,就变成了这个样子:

printf("max=%d",3!=3>1!=2?3!=3:1!=2);

这个时候大于号(>)的优先级更高,所以就出现了问题了。

优化上面的代码

可能很多人已经想到了解决方法了,比较有经验的工程师基本也比较少犯上面的错误。
加上括号就可以解决上面的问题了。

#define MAX(x,y) (x) > (y) ? (x) : (y)

OK,接下来我们再写一个测试程序

#define MAX(x,y) (x) > (y) ? (x) : (y)
int main(void)
{
    printf("sum =%d", 7 + MAX(3,4));
    return 0;
}

运行结果:
在这里插入图片描述
并不是我们所期望的11。我们将其展开后为:

7 + (3) > (4) ? (3) : (4);

这个时候加号(+)的优先级又比大于号(>)高,所以就出现了这种结果。

那我们就继续加个括号

#define MAX(x,y) ((x) > (y) ? (x) : (y))

到这里算是比较完整的了,在面试中要是能写出这个,那算基本功还是比较扎实的了。

那我们再写一个测试程序

#define MAX(x,y) ((x) > (y) ? (x) : (y))
int main(void)
{
    int i = 3;
    int j = 4;
    printf("max=%d",MAX(i++,j++));
    return 0;
}

运行结果:
在这里插入图片描述
这里面的j会做两次自增运算, 所以打印出来的结果是做了一次自增后的结果。

继续优化

#define MAX(type,x,y)({     \
    type _x = x;        \
    type _y = y;        \
    _x > _y ? _x : _y; \
})
int main(void)
{
    int i = 4;
    int j = 5;
    printf("max=%d\n",MAX(int,i++,j++));
    printf("max=%f\n",MAX(float,3.2,3.4));
    return 0;
}

到这里基本算比较完美了!是不是很折腾, 程序的bug就是这样一步一步修复的过程。

三、总结

如果你能一下就写出最后的代码,那说明你确实是666了,通过上面的一步一步分析是为了告诉大家,C语言真的有很多东西可以让我们去琢磨!我们也还有很长的路要走。

相关文章
|
缓存 安全 网络协议
HTTP和HTTPS的区别有哪些?
本文简要总结了 HTTP 和 HTTPS 的区别,从概念、端口、连接方式、使用场景、安全性等多个角度进行了对比。HTTP 是无状态的、无连接的应用层协议,适用于一般性网站和性能要求较高的应用;HTTPS 则通过 SSL/TLS 层提供加密、认证和完整性保护,适用于涉及敏感信息和高安全性的场景。文章还讨论了两者在性能上的差异,包括握手和加密开销、缓存效果以及 HTTP/2 的多路复用技术。最终,根据具体需求选择合适的协议能够更好地平衡安全性和性能。
4803 2
HTTP和HTTPS的区别有哪些?
|
网络协议 安全
|
开发者 Python
.py 和 .pyc 文件有什么区别?
【8月更文挑战第29天】
2098 1
|
存储 开发工具 git
Git 远程仓库地址管理:添加、修改和验证
Git 远程仓库地址管理:添加、修改和验证
996 4
|
消息中间件 算法 调度
FreeRTOS 任务调度和任务的状态
FreeRTOS 任务调度和任务的状态
FreeRTOS 任务调度和任务的状态
|
网络协议
逆向学习网络篇:心跳包与TCP服务器
逆向学习网络篇:心跳包与TCP服务器
588 0
到底什么是弱上下拉和强上下拉?
到底什么是弱上下拉和强上下拉?
|
存储 数据可视化
PS gif修改背景颜色(附加图片)
PS gif修改背景颜色(附加图片)
334 0
|
Web App开发 存储 JSON
http 和www HTTP与HTTPS的区别
http 和www HTTP与HTTPS的区别
http 和www HTTP与HTTPS的区别
显示接口之DBI
对于需要UI的产品来说,都会接触到各种各样的显示接口。接下来的几篇文章我们来整理一下常用的显示接口。