为什么这段 C 代码结果是 1?

2016-03-11 23:16:29 +08:00
 KyL

看到这么一道面试题

#include <stdio.h>
void main()
{
   int a=1,b=0,c=-1,d=0;
   d=++a||++b&&++c;
   printf("d=%d", d); //output 1;
   return;
}

我不理解为什么 d 会变成 1 而不是 2 。我知道所谓“短路”,但是无论如何,最左边 d=++a 这个表达式都会被 evaluate 啊。

#include <stdio.h>
void main()
{
   int a=1,b=0,c=-1,d=0;
   d=++a;
   printf("d=%d", d); //output 2
   return;
}

这个结果就得 2 。

为什么呢?

6135 次点击
所在节点    程序员
61 条回复
cuteshell
2016-03-12 16:42:52 +08:00
@zwpaper 是同优先级的,就像“+”和“-”一样,从左向右算。
wuhanchu
2016-03-12 16:58:54 +08:00
差点被你被你骗了
先算++a||++b&&++c 再赋值。。哎呀 这个问题 真是折磨人
vagarlee
2016-03-12 17:19:42 +08:00
d=(++a||++b&&++c)
++a||++b&&++c 的值返回的是 1 因为||
aksoft
2016-03-12 17:22:04 +08:00
码农和程序员的区别。
kingoldlucky
2016-03-12 17:59:01 +08:00
这道题真的很简单..真的很简单..
一眼扫过去就知道结果不是 0 就是 1
kingoldlucky
2016-03-12 18:00:16 +08:00
而且看完第一个++a|| 到这里了就知道结果一定为 1
只要有一个为真,表达式就为真
kingoldlucky
2016-03-12 18:02:27 +08:00
楼上那么多反对这道题的,C 语言真的是弱爆了,校招怎么找到工作啊.
Balthild
2016-03-12 18:26:26 +08:00
@wezzard 不是說 C99 裡面規定了 main 的類型如果是 int ,不寫返回值則默認返回 0 嗎?
Wonicon
2016-03-12 18:39:24 +08:00
@Balthild 问题是返回类型是 void ......
zwpaper
2016-03-12 18:58:16 +08:00
zwpaper
2016-03-12 19:12:58 +08:00
@kingoldlucky 请教一下,我从维基百科看到的运算符优先级中 && 是比 || 高一级的,那在一个语句里同时出现,为什么不处理 &&?
我知道 || 的短路效果,但是按优先级来看,难道不是应该先处理 && 吗?
从短路效果这点来看,无论什么运算,只要 || 前面为真,放在 || 之后都不运算,那 || 优先级的意义在哪?尤其是还专门分别给 && 和 || 定义 13 , 14 两个优先级。
https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
Viztor
2016-03-12 19:24:11 +08:00
这道题还可以啊。

@zwpaper
优先级的意思是:
A || B && C == A || (B && C)
!= (A || B) && C
kingoldlucky
2016-03-12 19:36:49 +08:00
@zwpaper 这道题 || 右边的所有结果对最后的 0 1 不构成影响
zwpaper
2016-03-12 19:47:38 +08:00
@Viztor 明白了,指的是结合优先级,而不是运算优先级,感谢!
nicevar
2016-03-12 21:05:22 +08:00
这种问题看汇编代码最清晰,哪能记得住那么多优先级
bp0
2016-03-13 00:03:10 +08:00
@KyL 这道题考的是前置++的运算时间,以及||和&&优先级的关系。

@zwpaper 不是不计算,而是还没开始计算就被跳过去了。如果优先级反过来,结果就是 0 了。

正因为&&的优先级高,所以表达式就像 @Viztor 说的是 ++A || (++B && ++C) ,算完++A 后,因为结果是 2 ,所以跳到给 d 赋值了(汇编级别而言)。

如果是||的优先级高,那么表达式就是 (++A || ++B) &&++C 。当++A 算完以后,不用算++B 。但是还要算++C 的,而 C 的初值是-1 。++C 的意思是先++,然后再&&。而-1 自增后是 0 。

所以,如果||的优先级高,那么 d 的值应该是 0 。
cuteshell
2016-03-13 12:23:22 +08:00
@zwpaper 是我弄错了,如果是同优先级++a||++b&&++c 的结果就是 false 了,应该是++a||(++b&&++c)就对了。
KyL
2016-03-13 13:46:09 +08:00
@theohateonion 谁说不是呢。这种代码老老实实用括号括起来就什么问题都没有。可是谁让很多公司就爱出这中面试题呢?
theohateonion
2016-03-13 14:47:55 +08:00
@KyL 我觉得公司这么考考虑的应该是看你对一门语言掌握的深度如何,其实这样还是有道理的,但是现在的情况是,作为一名大四狗,我在四年的学习中看到很多老师和教材也把这些题作为了教学的重点,导致很多学生失去了编程的兴趣,令人扼腕
theohateonion
2016-03-13 14:48:39 +08:00
@KyL 也可能是我们学校教学方面还存在着问题吧(西安某 985 )

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/262900

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX