int a = 0;
a = (++a) + (++a) + (++a) + (++a);
printf("%d\n", a);
gcc version: 4.9.2
不太懂为什么 a 会等于 11?能分析一下吗?
1
skybr 2015-02-09 23:13:14 +08:00 9
别分析了, 写出这种代码的都被打死了.
|
2
scusjs 2015-02-09 23:15:32 +08:00 1
看看汇编就知道了。。会各种坑爹的优化啥的。ps. 这种代码纯属蛋疼
|
5
zkd8907 2015-02-09 23:17:34 +08:00 2
分析的结果就是如果我们的团队里有人写这种代码直接Failed Code Review。。
|
6
xdeng 2015-02-09 23:35:21 +08:00 1
谁吃饱了 写这样的代码
|
7
Do 2015-02-09 23:36:59 +08:00 1
这代码应该是体育老师教的
|
8
Sharuru 2015-02-09 23:37:03 +08:00 1
看汇编代码+1
编译器实现+1 Po 主可以搜索有关 C语言和自增运算的相关文章,简单来说结果完全是看编译器是怎么实现的。 |
9
LMkillme 2015-02-09 23:37:54 +08:00 6
我特想知道,开这种题目先河的是不是谭浩强?
|
11
txx 2015-02-09 23:44:28 +08:00 via iPhone 2
这种题 不同编译器 结果不同 不同参数 结果不同
|
12
disonlee 2015-02-09 23:50:46 +08:00 1
同楼上,编译器不同,结果不同的。写这代码明显是小白装大神。
|
13
hjc4869 2015-02-09 23:52:20 +08:00 1
楼主,VC2013和C#里这个结果都是16。各自都有各自的解释,这种代码出现在现实生活中就是一个字:死。
|
14
igboy OP |
15
vibbow 2015-02-09 23:55:38 +08:00
PHP给的结果是 10
|
16
spacewander 2015-02-10 00:02:15 +08:00
不如我们试试看,不同的编译器/编程语言会得出一共多少种答案?;)
|
17
LMkillme 2015-02-10 00:10:07 +08:00
@spacewander 编译器还那么多版本呢。。。要不都测一遍?我支持你~
|
18
adjusted 2015-02-10 00:12:24 +08:00
这种还是要做过编译器的专业人士来解释
|
19
acros 2015-02-10 00:21:35 +08:00
两点明白了就好:
前置自增运算符的特点, “+”运算符的结合方向 (这个好像不同编译器表现不一样?) |
20
jsq2627 2015-02-10 00:30:34 +08:00
这种属于 undefined behavior
参见 http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points |
21
BGLL 2015-02-10 00:32:35 +08:00 via Android
任意两个顺序点之间的副作用的发都是未定义的.
这是未定义行为,a=a++都是未定义行为,是错误的…… |
22
ostholz 2015-02-10 00:33:42 +08:00
llvm 3.5 编译出来的结果是 10
swift 结果也是 10 |
23
yellowV2ex 2015-02-10 00:34:12 +08:00
口算应该是 10 啊
|
24
BGLL 2015-02-10 00:44:53 +08:00 via Android
这个编译器应该会有等于
16(4+4+4+4) 和 11(2+2+3+4) 两种结果 |
25
geeti 2015-02-10 00:49:37 +08:00
谭浩强的书看多了就爱思考这种问题
|
26
BGLL 2015-02-10 00:51:51 +08:00 via Android
我说的是 c\c++
第一步:(++a) + (++a)编译器会的当成 ++a;(a==1 ++a;(a==2 a+a;表达式值==2+2==4 后面就是4+ (++a),楼主应该懂了 这种式子是未定义行为是错误的,要是有题目出这种东西,使劲喷 |
27
BGLL 2015-02-10 01:05:19 +08:00 via Android
++a;(a==1
++a;(a==2 a+a;表达式值==2+2==4(a=2 4+ (++a)==4+3==7(a=3 7+(++a)==7+4==11 - ++a; ++a; ++a; ++a; a+a+a+a==16; |
28
zsj950618 2015-02-10 01:10:36 +08:00
这应该是编译原理的作业吧。。。
|
29
xfwduke 2015-02-10 02:02:33 +08:00
movl $0, 28(%esp)
addl $1, 28(%esp) addl $1, 28(%esp) movl 28(%esp), %eax leal (%eax,%eax), %edx addl $1, 28(%esp) movl 28(%esp), %eax addl %edx, %eax addl $1, 28(%esp) addl %eax, 28(%esp) movl 28(%esp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf 直接看这个最明了了 |
30
msg7086 2015-02-10 04:04:35 +08:00
语句是非法的,搞懂了也没意义。
|
31
ispinfx 2015-02-10 08:17:36 +08:00 via iPhone
No zuo no die why you try!
|
32
invite 2015-02-10 08:45:48 +08:00
因为规定好了。
|
33
chrishine 2015-02-10 08:52:46 +08:00
很多人默默的B了就行了.
楼主这种的, 要给5个铜币. |
34
yuankui 2015-02-10 09:09:53 +08:00
这种问题好无聊...
|
35
quericy 2015-02-10 09:12:24 +08:00
这种问题,也就谭++和应试教育喜欢出~~~~
|
36
singer 2015-02-10 09:24:51 +08:00 via iPhone
幸好学的时候,老师说谭浩强的太傻逼,直接换其他书上了。搞得我们全班比其他平行班C语言牛逼好多。只能说别学太死了。。。。能编程,这项目,就好了,不要去纠结没意义的题目啊。
|
37
loveuqian 2015-02-10 09:36:29 +08:00
<script type="text/javascript">
var a = 0; a = (++a) + (++a) + (++a) + (++a); document.write(a) </script> 答案是10喔 |
38
jasonding 2015-02-10 09:53:51 +08:00
研究了下,JAVA这个题的答案是10。
a=(++a) ; 此时a=1 a=(++a)+(++a) : a=1 + (++1) 此时打印结果为3; a=(++a)+(++a) +(++a) : a=1 + (++1) +(++(1 + (++1))) 此时打印结果为6; a=(++a)+(++a) +(++a)+(++a) : a=1 + (++1) +(++(1 + (++1)))+(++(1 + (++1) +(++(1 + (++1))))) 此时打印结果为10。 但是11就不知道怎么来的了 |
39
jasonding 2015-02-10 09:56:15 +08:00
打印结果为10那一行写错了,cao
a=(++a)+(++a) +(++a)+(++a) : a=1 + (++1) +(++(1 + (++1)))+(++(++(1 + (++1))) 这样才是对的 |
40
robertlyc 2015-02-10 10:20:04 +08:00
没啥 为什么
编译器就是这么做的 而且各家编译器还不同 不需要理解 除非你未来工作是写/优化编译器 |
41
frankzeng 2015-02-10 10:35:03 +08:00
各位别不服气,去大公司应聘,笔试不就考这些吗
|
42
Narcissu5 2015-02-10 10:39:47 +08:00
我记得C语言对这种带副作用的表达式的求值和传值顺序是未定义的
so,出现什么结果都有可能,就不要深究啦 |
44
Dongdong36 2015-02-10 11:30:41 +08:00
不需要知道为什么,因为没人会写这种代码,如果想知道原理,就拆分开,一点点试验,分析编译器的处理顺序,不同的编译器对于未定义的操作处理方法是不同的,曾经就遇到过gcc和VS的编译结果不同。
|
46
BGLL 2015-02-10 11:43:12 +08:00
@jasonding 楼主的题是C\C++,
C\C++里第一步 a=(++a)+(++a) 可以等于3也可以等于4,看编译器,因为这是未定义行为(也就是错误写法) 等于4的顺序是 ++a , a =1了 ++a,a=2了 a+a,2+2=4了 |
47
b821025551b 2015-02-10 11:46:02 +08:00
这是谭浩强书上的作业吧?
|
48
clino 2015-02-10 11:55:58 +08:00
为什么我用gcc编译不过呢
t.c:3:1: warning: data definition has no type or storage class [enabled by default] a = (++a) + (++a) + (++a) + (++a); ^ t.c:3:1: error: redefinition of ‘a’ t.c:2:5: note: previous definition of ‘a’ was here int a = 0; ^ t.c:3:1: error: initializer element is not constant a = (++a) + (++a) + (++a) + (++a); ^ t.c:4:8: error: expected declaration specifiers or ‘...’ before string constant printf("%d\n", a); ^ t.c:4:16: error: expected declaration specifiers or ‘...’ before ‘a’ printf("%d\n", a); ^ |
49
kofj 2015-02-10 11:56:28 +08:00
表示Golang直接syntax error: unexpected ++
|
50
xuyuanp 2015-02-10 12:04:14 +08:00
谭浩强教的
|
52
frankzeng 2015-02-10 12:34:56 +08:00
@BGLL 虽然不是这题,但也差不多啊
int a = 4; (A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++); a = ? 说实在的,在程序中用这种奇技淫巧,保证不打死他 |
53
ceclinux 2015-02-10 12:49:24 +08:00
以前觉得懂这个很牛逼
现在看这种无聊的代码就想吐 |
56
josephok 2015-02-10 13:49:21 +08:00
undefined
|
57
belin520 2015-02-10 13:57:07 +08:00
哈哈,楼主被喷的,,连谭浩强也跟着躺枪了。。
|
58
BGLL 2015-02-10 13:57:10 +08:00
@frankzeng
这已经不是奇巧淫技了,是错误写法了,如果有题目是要指出这个是错误的还可以理解。 要求值那肯定是出题人自己连 C\C++ 的顺序点、副作用是什么都不知道。 本身就是错的语句,考什么?考想象力?这题4个语句都是未定义语句,可以让a等于任何整数值,完全取决于编译器作者心情。 |
59
fannas 2015-02-10 14:28:25 +08:00 via Android
@谭浩强
|
60
b821025551b 2015-02-10 14:33:24 +08:00 1
@belin520 作为一个曾经的全日制本科生,可以告诉你这道题就是在谭浩强的书上出来的,我还清楚的记得当时用java和c运行出两种结果,屁颠颠地去问个老教授,得到的回复是java就得10,C就得11,没有为什么;再之后用vc和devC又出了两种结果,再然后我那门课挂掉了。。。
|
61
hooluupog 2015-02-10 14:39:41 +08:00
Go直接报错~~
|
62
onemoo 2015-02-10 14:42:50 +08:00
楼上很多人都说了,这个行为是undefined。
用这几个关键字去google吧:副作用(side effect)、序列点(sequence point) 虽然是未定义的,但如果你想知道你的gcc是用什么样的实现来得到这个结果的 ,请查看汇编:objdump -d |
64
facat 2015-02-10 14:55:23 +08:00
标准里面没有规定++运算符的优先级,是编译器自己实现的。
|
66
BGLL 2015-02-10 15:05:31 +08:00
@b821025551b
难怪,那么多人喷谭浩强.... |
67
onlyice 2015-02-10 15:27:15 +08:00
求不问这种问题。。
自己搜一下就知道了。。 |
68
vwok 2015-02-10 20:02:20 +08:00 via Android
对于扯这种问题的,可以把四个括号去掉让他在算算等于多少
|