关于++i与i++的总结

大牛的总结(详见《C专家编程》一书附录A):

++X和X++的区别与编译器的中间代码有关,例如:

“++X”表示取X的地址,增加它的内容,然后把值放在寄存器中;(先加)

“X++”表示取X的地址,把它的值装入寄存器中,然后增加内存中X的值;(后加)

 

测试代码如下:

#include<stdio.h>
int main( )
{
    int a=1,b=3;
    int c=0;
    c=a++;
    printf("c=%d\n",c);
    c=++b;
    printf("c=%d\n",c);
    return 0;
}

汇编代码如下:

0x00401334	push   %ebp
0x00401335	mov    %esp,%ebp
0x00401337	and    $0xfffffff0,%esp
0x0040133A	sub    $0x20,%esp
0x0040133D	call   0x401960 <__main>
0x00401342	movl   $0x1,0x1c(%esp)
0x0040134A	movl   $0x3,0x18(%esp)
0x00401352	movl   $0x0,0x14(%esp)
0x0040135A	mov    0x1c(%esp),%eax
0x0040135E	mov    %eax,0x14(%esp)
0x00401362	incl   0x1c(%esp)           '为c=a++;对应的汇编代码
0x00401366	mov    0x14(%esp),%eax
0x0040136A	mov    %eax,0x4(%esp)
0x0040136E	movl   $0x403024,(%esp)
0x00401375	call   0x401bd0 <printf>
0x0040137A	incl   0x18(%esp)
0x0040137E	mov    0x18(%esp),%eax
0x00401382	mov    %eax,0x14(%esp)     '为c=++b;对应的汇编代码
0x00401386	mov    0x14(%esp),%eax
0x0040138A	mov    %eax,0x4(%esp)
0x0040138E	movl   $0x403024,(%esp)
0x00401395	call   0x401bd0 <printf>
0x0040139A	mov    $0x0,%eax
0x0040139F	leave
0x004013A0	ret

运行结果如下:



分析如下:

从汇编代码中可以看出,

当程序在运行“c=a++“代码时,可以看出是先将a地址的值放入了寄存器中,然后将寄存器的值赋值给c,最后增加a地址内容的值。

当程序在运行"c=++b"代码时,可以看出是先将b地址的值加1,然后放入了寄存器中,最后将寄存器的值赋值给c。

 

很多在学C语言基础的同学中,往往对i++和++i的概念混淆不清。

实验环境:CodeBlocks13.12

其实可以简单的这么理解。

case 1:

如果仅仅是i++或者是++i单独成行构成一条语句的话,没有区别,最终都等效与i=i+1;

case 2:

如果不是单独构成一条语句,并且在所构的成语句当中含有其他运算符。则其运算原则为:

int i=3;

j=i++;  //先执行赋值运算符,即j=3; 然后自增 i=i+1;

最终:i=4;j=3

 

int i=3;

j=++i;  //先执行自增 i=i+1;即i=4; 然后执行赋值运算,即j=i;即j=4;

最终:i=4;j=4

case 3:

如果在输出语句中,情况又有所不同了:

    int i=3;
    printf("%d %d %d\n",i,++i,++i); //输出是 5 5 5

分析如下,在printf中,首先按自右至左的顺序求参数的值;然后输出。

运算过程如下:

先计算最右边的++i;运算过后i=4;

然后计算左边的++i;运算过后i=5;

因此最后i=5;而输出的都是i的值,因此输出是5 5 5;

 

如果是i++的情况又有所不同了:

    int i=3;
    printf("%d %d %d\n",i,i++,i++); //输出是 5 4 3

分析如下:首先按自右至左的顺序求出参数值,求出一个输出一个;等价于:

%d=i++;  //由Case 2 可知,输出为3,此时i=4

%d=i++;//同理输出为4,此时i=5;

%d=i;//输出为5

那么

    int i=3;
    printf("%d %d %d\n",i,i++,++i);

输出又是多少呢?

输出为:5 4 5;你答对了吗?

总结:在输出当中,涉及到++i的运算,需待所有运算结束后,再输出。而i++的运算则是先输出,再进行运算。

 

Uplevel:

Case 4:

如果在输出当中除了++运算符,还惨杂其他运算符又该如何输出呢?

    int i=3;
   printf("%d %d\n",i,++i+1);//输出4 5

整个运算过程如同Case 3中的i++类似:

%d=++i+1;//输出为 5,此时i=4

%d=i;//输出为4

总结:若++i中还包含其他运算符,则它原有的输出顺序被打乱,此时的输出顺序如同i++;会运算完就输出。

Case 5:

如果在赋值运算过程中有其他运算符,那么结果又是如何呢?

    int i=3;
   int j=i+++2;
   printf("%d %d\n",i,j);//输出为4 5

分析如下:

首先执行加法,即i+2;然后执行赋值运算符j=i+2;即j=5;最后执行自增运算符i=i+1,即i=4.

又如:

    int i=3;
   int j=++i+2;
   printf("%d %d\n",i,j);//输出为4 6

运算过程又是怎样呢?分析如下:

显然先执行自增运算符i=i+1;即i=4;再执行加法,最后执行赋值。即j=i+2;即j=6;

 

尽管表达式可以千变万化,关键还是得搞清楚他们的执行顺序是怎样的,按照优先级和结合性按部就班就可以融会贯通了。

自减运算符同自增运算符。

此处值得注意的是:-和++为同一优先级,结合方向为自右向左,所有-i++相当于-(i++);//此处不是减号运算符,减号运算符优先级比++要低,此处是负号运算符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值