想求教一个问题。高手进

时间:2022-11-28 18:54:07
就是当用"="执行赋值操作的时候,如果等号两边都需要先求值的话,那么两边的求值和最终的赋值的顺序到底是如何的?
说得形象一点的话就是下面这个例子。
i=0;
while(i<N)
a[i++]=b[i];


i=0;
while(i<N)
a[i]=b[i++];

11 个解决方案

#1


标准木油规定

#2


这个找个编译器编译下很好解决吧...一般也不会用这么晦涩的代码

#3



while(i<N)
0032136E  cmp         dword ptr [i (327188h)],0Ah  
00321375  jge         wmain+4Fh (32139Fh)  
a[i++]=b[i];
00321377  mov         eax,dword ptr [i (327188h)]  
0032137C  mov         ecx,dword ptr [i (327188h)]  
00321382  mov         edx,dword ptr b (327138h)[ecx*4]  
00321389  mov         dword ptr a (327160h)[eax*4],edx  
00321390  mov         eax,dword ptr [i (327188h)]  
00321395  add         eax,1  
00321398  mov         dword ptr [i (327188h)],eax  

供参考 VS2010反汇编

#4


只要等号两边,不同时对一个变量赋值(包含自加自减),那么表达式的顺序是可以理解的。

不过不管怎么样,这都属于不推荐行为,实际编程中谁这么写,是想炫耀代码技巧还是为难自己或同事呢?

#5


引用 4 楼 nibiewuxuanze 的回复:
只要等号两边,不同时对一个变量赋值(包含自加自减),那么表达式的顺序是可以理解的。

不过不管怎么样,这都属于不推荐行为,实际编程中谁这么写,是想炫耀代码技巧还是为难自己或同事呢?

编译器不同顺序可能不一样;
一般写代码也是把右边的赋值给左边啦。

#6


当用"="执行赋值操作的时候, 右边的表达式的值赋于左边表达式(如果是 l-value),其它问题需要具体分析

你的例子中关键是序列点的问题,看
http://topic.csdn.net/u/20110826/09/601EBE9C-C2AE-4D63-A4E2-506C618BB654.html

#7


还是汇编厉害啊

#8


VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

不要写连自己也预测不了结果的代码!

#9


我的运行结果显示两者一样,并且与int i=0;      等价。
                           while(i<N)
                          {
                              a[i]=b[i];
                              i++;
                           } 

#10


纠结于这样的问题很没意义啊,跟编译器有关。

#11


是根据运算符的先后级来操作的,等号是最低级的,赋值肯定是由右向左赋值

#1


标准木油规定

#2


这个找个编译器编译下很好解决吧...一般也不会用这么晦涩的代码

#3



while(i<N)
0032136E  cmp         dword ptr [i (327188h)],0Ah  
00321375  jge         wmain+4Fh (32139Fh)  
a[i++]=b[i];
00321377  mov         eax,dword ptr [i (327188h)]  
0032137C  mov         ecx,dword ptr [i (327188h)]  
00321382  mov         edx,dword ptr b (327138h)[ecx*4]  
00321389  mov         dword ptr a (327160h)[eax*4],edx  
00321390  mov         eax,dword ptr [i (327188h)]  
00321395  add         eax,1  
00321398  mov         dword ptr [i (327188h)],eax  

供参考 VS2010反汇编

#4


只要等号两边,不同时对一个变量赋值(包含自加自减),那么表达式的顺序是可以理解的。

不过不管怎么样,这都属于不推荐行为,实际编程中谁这么写,是想炫耀代码技巧还是为难自己或同事呢?

#5


引用 4 楼 nibiewuxuanze 的回复:
只要等号两边,不同时对一个变量赋值(包含自加自减),那么表达式的顺序是可以理解的。

不过不管怎么样,这都属于不推荐行为,实际编程中谁这么写,是想炫耀代码技巧还是为难自己或同事呢?

编译器不同顺序可能不一样;
一般写代码也是把右边的赋值给左边啦。

#6


当用"="执行赋值操作的时候, 右边的表达式的值赋于左边表达式(如果是 l-value),其它问题需要具体分析

你的例子中关键是序列点的问题,看
http://topic.csdn.net/u/20110826/09/601EBE9C-C2AE-4D63-A4E2-506C618BB654.html

#7


还是汇编厉害啊

#8


VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

不要写连自己也预测不了结果的代码!

#9


我的运行结果显示两者一样,并且与int i=0;      等价。
                           while(i<N)
                          {
                              a[i]=b[i];
                              i++;
                           } 

#10


纠结于这样的问题很没意义啊,跟编译器有关。

#11


是根据运算符的先后级来操作的,等号是最低级的,赋值肯定是由右向左赋值