篇幅有点长,让您受累了。。。
a++这个问题一直很困扰,自己做了个测试,虽然都知道a++是先使用
a再进行自加,疑问点就是这个a使用的期限是什么时候结束?一开始以为是表达式代码行完成后,在第二行代码需要试用a时,就是自加结果,这也是最常用的情况,也很好理解,如:
int a=0,b;
b=a++;
printf("a=%d b=%d",a,b);//输出:a=1,b=0
那假如在同一行表达式中出现2次a++,也就是说a++后又与其他变量进行运算,如下代码:
int a=10,b=0;
b=a+++a++;
printf("a=%d b=%d",a,b);//输出a=12 b=21
如果上面的理论成立那b应该等于20,根据执行结果显然不成立,所以我觉得应该是当执行a++运算时,a还是10,但当a在与其他变量继续运算时a就已经完成了自增,就是自增后的值与其他变量运算了,在变下代码再测试:
int a=10,b=0;
b=a+++b;//b=10(因为a++优先级大于++b,所以直观点应该是b=(a++)+b,尽管此时括号是多余的)
显然这种说法也不成立。
对b=a+++a++运算的猜测步骤为:
第一个a++ //此时a=10
第二个a++ //因为第一步运算完后a自增1,所以此时a=11,是第一个a++运算后的值
b=a+a //b=11+11=22,这点就不理解了,之所以最终结果这个b=21,难道是b=10+11吗,但中间+号的表达式两端都是a,应该两端的值都是一样的啊,应是22或20啊,怎么会是21,b=(a++)+(++a) 这个结果为22,应该可以说明+号两边都是a的话,第一个表达式a++中a会被++a后的值覆盖,所以b=11+11。
求解释b=a++a++的详细运算步骤,为啥会是b=21?
还有个问题:
int i=1;
int j=0;
for(;j<5;j++){
i=i++;
printf("i=%d",i);
}
printf("i=%d",i);
为什么i=1?为什么i=i++执行完后,在执行j<5之前或在下一轮执行前i没有自加?及时for循环中i=1,那for循环执行完后i应该至少会加1吧,起码i也得等于2啊?
I also struggled with these grammatical features when I was learning. In fact, even if these are written together, the standard does not define how to implement them.
So the specific results depend on the compiler. So if the compiler is different, the specific results may be different.
So in practice, this way of writing should be avoided to avoid deceptive mistakes.
This type of code can help us understand some rules of the C language, but it is best not to appear in this way of writing in actual projects, because maybe after a few months when you go back to maintain the code and see this, you will feel confused, or others will Maintaining your code will make you want to strangle you. Okay, let’s talk about a+++a++. When the compiler compiles, there is a rule called the greedy method. If you read in as many symbols as possible at one time, you can read a++ all the way from the beginning, so this can be concluded as (a++) +(a++), but the result I obtained using gcc4.5.1 is 20. It can be seen that the compilation results of different compilers are different, maybe there is optimization. Therefore, once again, do not write this kind of code into actual projects! A good programmer is one who can write clean and clear code.
I am the author of the link mentioned above.
At the same time, take a look at the pictures from the analysis:
The disassembly code is here:
Of course, this is under vc++, g++ , the compilation result of clang is different from this.
At the same time, there is also the issue of the order of operations of Java and C++ that was previously answered for reference:
This issue has nothing to do with operators, they are all calculated from right to left, but the compiler's processing of value types Differences caused by inconsistent results.
For gc-like languages, including (
java
,c#
,php
,javascript
), etc., the intermediate operation results of single-sentence instructions will be cached. Since C/C++ is directly compiled into assembly instructions and does not have the support of a virtual machine or engine, this step will not be possible.In layman’s terms, for c++:
That is to say, the value of a is a value type and will be updated at any time as a changes. No matter what value a is initially set to, the result is 0. (a-a).
However, for other languages, the virtual machine or engine will automatically save the calculation results of each step.
Above.
Extension: Research on a weird addition algorithm in PHP
Although there is such a syntax, it is equivalent to classical Chinese in programming, which will only increase the difficulty of reading the program. If you write this kind of code in an actual project, you will definitely be criticized
It feels like what was said above, it all depends on the mood of the major compilers...
Many years ago, I remember that TC2.0 and VC6 handled this differently, so don’t worry about it.
Secondly, writing like this is not allowed in official projects.
Excerpted from Professor Qiu Zongyan’s article, which should be the clearest explanation in the Chinese version. http://www.math.pku.edu.cn/teachers/qiuzy/technotes/expression2009.pdf The best answer above explains the results from the implementation principle, but as Professor Qiu Zongyan pointed out, this issue is at the normative level. Not only is this type of code difficult to understand and should not be written in the project, but it cannot be written according to the normal definition.