欢迎光临散文网 会员登陆 & 注册

5段反人类代码测测你对C语言基础的理解深度

2021-09-21 21:47 作者:奥大梨呀  | 我要投稿

        我们在学习C语言的时候,通常都会看到书上存在i+++i++这种反人类写法,不仅如此,对于一些C语言的考试也会存在一些我们平常在开发时完全不可能使用的自找麻烦写法。虽然说这些代码容易使人血压升高,但其实也从侧面反应出我们对C语言部分知识点的掌握和理解。下面有一些反人类写法,仅供学习,试试看你能答对几个呢。

1.下面的程序会输出什么结果呢?

题1程序

.

.

.

.

.

.

.

.

.

.

        如果你的答案是3 3的话,那么恭喜你,你已经理解了逗号运算符的优先级,他是所有运算符中优先级最低的,没错,比赋值运算符“=”还低,因此上述程序会将a和b赋值为3,至于 b + 1,有极大的可能会被编译器优化掉(见下文)。

2.如果在1.的代码中稍加修改,又会输出什么结果呢?

题2程序


.

.

.

.

.

.

.

.

.

        这里与1.的区别在于将表达式的后半部分加上了圆括号,确保了对a的赋值在最后进行。如果你理解逗号运算符的另一个特点:从左算起,以最右边的表达式值为最终值。那么应该不难得到正确答案4 3。

顺便提一点,在这段程序中,b + 1并没有被编译器优化掉,对比两者的汇编代码即可得知:

题1汇编代码
题2汇编代码

3.下面的程序如果输入 1 5 回车,会输出什么结果呢?

 

题3程序


.

.

.

.

.

.

.

.

.

        对scanf()这个函数有了解的小伙伴肯定就想到了,结果是1 0而不是1 5。scanf()的输入必须严格按照格式字符串中的格式输入,上述程序scanf()的格式字符串中,两个%d之间存在着一个逗号,则若想输出 1 5,则输入时必须将逗号也输入,即1,5。

4.下面的程序会输出什么结果呢?

题4程序


.

.

.

.

.

.

.

.

.

.

        按我们正常的角度理解,应该会输出0 20。但结果却是 -1 20。这是因为C语言的类型隐式转换的层级unsigned int 是大于int的,因此会先将a转换为unsigned int 类型,再与b进行比较。而a的值为-1,在内存中负数以补码的方式存储,-1对应的补码即0xffffffff,直接转换成无符号十进制数则是4294967295,很明显,20是不可能大于这个数的,因此if后的条件也不成立,自然就不会执行a自增1。

5.下面的程序会什么结果呢?

题5程序


.

.

.

.

.

.

.

.

.

        如果你觉得答案是1 0的话,那么就错了。正确答案应该是0 0。按正常思路,首先b为0,条件表达式的值为 : 后的表达式的值,之后a自增1,那么结果a应该是1。这么想的话,就忽略了一个重要的因素,++运算符的优先级是比条件运算 ? 高的。因此表达式的执行流程应该是这样的:先计算a++,由于++在后,先使用a的值0,此时表达式变成了这样:

a = b ? 1 : 0;

之后,a自增1,此时a为1是没错的。执行完a++之后,开始执行条件表达式 ? ,很明显,b为0,那么条件表达式的值为 : 后的内容即0,再对a赋值0,此时a为0。 通过这个分析我们可以知道,a++是有使a自增1的,但是在之后被赋值0覆盖了,因此a的最终值才会是0而不是1。

上述程序如果从汇编代码来看就非常清晰了:

题5汇编代码

        反人类代码是绝对不能出现于实际开发中,否则绝对绝对是自找麻烦。但是读一读这些代码还是可以加深对C语言一些知识的理解的。



5段反人类代码测测你对C语言基础的理解深度的评论 (共 条)

分享到微博请遵守国家法律