一直以为自己会++的操作与逻辑,但是每次都碰壁,然后就各种实验和总结,当反复确认自己熟记后,然而又忘了。
所以好记性不如烂笔头,简单的东西也要写笔记!
下面对C语言在++运算符总结:
自增运算符(++),分为前缀形式(++x)和后缀形式(x++)。
当表达式中只有一个自增运算符时,比较简单。但是当一个表达式中存在多个++时,会发生什么?
答案当然不止一种,不同语言可能不同,不同编译器也会不同,我只总结了 gcc 4.8.5 的情况。
查看gcc版本:
gcc -dumpversion
两个++时:
int i=1; int j = i++ + i++;
由于运算符的优先级 j = (i++) + (i++) —> j = (1++) + (2++) —> j = (1) + (2)
i = 3 , j = 3
两个括号内都是先取i当前的值,然后才自增的,此时后面的i是前面i自增后的值,取值后在自增。
int i=1; int j = ++i + ++i;
由于运算符的优先级 j = (++i) + (++i) —> j = (++1) + (++2) —> j = (3) + (3)
i = 3 , j = 6
两个括号内都是先运算再取值,表达式结束后前面的i和后面的i为相同值,
汇编代码为:
movl $3, -4(%ebp) ;3->i leal -4(%ebp), %eax ;&i->eax incl (%eax) ;i++,即i=4 leal -4(%ebp), %eax ;&i->eax incl (%eax) ;i++, i=5 movl -4(%ebp), %eax ;i->eax, eax=5 addl -4(%ebp), %eax ;i+i ->eax ,eax=10 movl %eax, -8(%ebp) ;10->j
VC/gcc生成的是本地代码,而X86处理器是基于寄存器的架构,也就是如果它要进行了两个数相加,它会先把两个数移到寄存器,再进行加法运算。而Java虚拟机是一种基于栈的架构,如果它要进行两个数相加,它会先弹出两个数,再进行加法运算,再将结果入栈。
int i=1; int j = ++i + i++;
由于运算符的优先级 j = (++i) + (i++) —> j = (++1) + (2++) —> j = (3) + (2)
i = 3 , j = 5
前括号内都是先运算再取值,后括号是先取值在运算。
int i=1; int j = i++ + ++i;
由于运算符的优先级 j = (i++) + (++i) —> j = (1++) + (++2) —> j = (1) + (3)
i = 3 , j = 4
前括号内是是先取值在运算,后括号是先运算再取值。
当只有两个项时,前+不管在哪都是表达式结束前在赋值。
三个++时:
int i=1; int j = i++ + i++ + i++;
由于运算符的优先级 j = (i++) + (i++) + (i++) —> j = ((1++) + (2++)) +(3++)—> j = ((1) + (2)) + (3)
i = 4 , j = 6
三个括号内都是先取i当前的值,然后才自增的,此时后面的i是前面i自增后的值,取值后在自增。
int i=1; int j = ++i + ++i + i++;
由于运算符的优先级 j = (++i) + (++i) + (++i) —> j = ((++1) + (++2)) +(++3)—> j = ((3) + (3)) + (4)
i = 4 , j = 10
三个括号内都是先运算再取值,在同一个括号内的相同变量值相同。
当有多个++运算符时,表达式遵守加法结合律,前面两个相加后,在于后面的运算。