C语言优先级和(i++)+(i++)与(++i)+(++i)

转载 2012年03月30日 21:48:28

在网上看到了这篇文章,很不错就转载了,摘自:http://www.cnblogs.com/hustcat/archive/2009/06/02/1494311.html

与在前面:++(--)有太多让人困惑的地方,(i++)+(i++)与(++i)+(++i)有什么不同?为什么不同?如果从机器的角度去理解,就会豁然开朗。

 先来看段程序:


int main()
{
    int i=3;
    int j=(i++)+(i++);
    
//    int j=(++i)+(++i);
    printf("%d,%d\n",i,j);
}


(1)在VC 6.0下:

对于(i++)+(i++):
结果:i=5,j=6

相应的汇编代码为(有详细注释):

8B 45 FC             mov         eax,dword ptr [ebp-4]   ;i->eax
03 45 FC             add         eax,dword ptr [ebp-4]    ;i+i=6
89 45 F8             mov         dword ptr [ebp-8],eax    ;6->j
8B 4D FC             mov         ecx,dword ptr [ebp-4]    ;i->ecx(=3)
83 C1 01             add         ecx,1                           ;ecx=4
89 4D FC             mov         dword ptr [ebp-4],ecx    ;4->i
8B 55 FC             mov         edx,dword ptr [ebp-4]    ;i->edx
83 C2 01             add         edx,1                           ;edx=5
89 55 FC             mov         dword ptr [ebp-4],edx    ;5->i

对于(++i)+(++i):
结果:i=5,j=10
相应的汇编代码为:

8B 45 FC             mov         eax,dword ptr [ebp-4]    ;i->eax (=3)
83 C0 01             add         eax,1                           ;eax=4
89 45 FC             mov         dword ptr [ebp-4],eax    ;4->i
8B 4D FC             mov         ecx,dword ptr [ebp-4]    ;i->ecx
83 C1 01             add         ecx,1                           ;ecx=5
89 4D FC             mov         dword ptr [ebp-4],ecx    ;5->i
8B 55 FC             mov         edx,dword ptr [ebp-4]    ;i->edx
03 55 FC             add         edx,dword ptr [ebp-4]    ;edx=10 ,即i+i
89 55 F8             mov         dword ptr [ebp-8],edx    ;10->j


(2)在gcc 3.2.2下:

对于(i++)+(i++):

结果:i=5,j=6相应的汇编代码为:


c7 45 fc 03 00 00 00     movl    $3, -4(%ebp)        ;3->i
8b 55 fc        movl    -4(%ebp), %edx        ;i->edx (=3)
8b 45 fc        movl    -4(%ebp), %eax        ;i->eax    (=3)
8d 04 10         leal    (%eax,%edx), %eax     ;i+i=6 ->eax
89 45 f8        movl    %eax, -8(%ebp)        ;6->j
8d 45 fc        leal    -4(%ebp), %eax        ;&i->eax
ff 00            incl    (%eax)            ;i++ ,即i=4,注意这里为寄存器间接寻址
8d 45 fc        leal    -4(%ebp), %eax        ;&i->eax
ff 00            incl    (%eax)                ;i++,即i=5

对于(++i)+(++i):
结果:i=5,j=10
相应的汇编代码为:


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

可见,对于VC6.0和gcc,二者的结果一致,但是gcc 3.2.2生成的汇编代码明显比VC6.0高效、简洁。这也许是因为VC 6.0出现较早的原因吧。

代码本身是没有意义,但是通过这段代码却可以理解机器层面的东西,而这也是我想表达的。


事实上,C#语言及Java语言对表达式的副作用及在运算中的表现有严格的规定,也就是说,有确定的答案。但在C及C++,没有确定的答案,因为这在语言中没有规定,是由编译器来决定的。
从这个角度看,永远不要写出这种“应试教育”的产物。




++i 和 i++ 的理解

C语言初学者易理解错误的自增运算符

逆时针打印矩阵

金山的笔试题目:给一个矩阵,将矩阵逆时针打印出来
  • yilip
  • yilip
  • 2014年11月27日 13:53
  • 1822

[字符串常量]是如何储存的

问题:你有没有想过,当你声明一个简单的字符串常量的时候,发生了什么?这些字符串放到了哪里?讲道理,这里的变量 str 是该字符串的地址,那么hello world存到了哪里?char *str="he...

C语言 文件I/O:实现结构体数据 存储到文件和从文件读取

这是一个初步试验!是为了下一步的创建班级学生管理系统做准备 ClassInfo.h源码 #define MAX_STUDENT 50 //班级最大学生人数 #define MAX_NAME_SPA...

C语言标准I/O函数及其特点总结

C语言的标准I/O库通过系统调用同内核打交道,内核通过驱动和硬件打交道。由于CPU要处理很多任务,所以和低速的I/O的交互一般要经过中间的缓存。    标准I/O库有几个常用函数,虽然很常见,但是其...

c语言的I/O重定向的能力

1. C语言是没有I/O的语言          C语言本身就是没有I/O能力的语言,是依靠函数模块来完成的。如printf()就是一个I/O函数,在编译时,编译器并不编译printf()函数,而把...

C语言学习大纲--I/O流

专题八:I/O流与标准库 1.     IO流的打开和关闭         FILE* fopen (                                         constcha...

【C语言】”student a am i “和“we are happy”

1.有一个字符数组的内容为 : “student a am i”, 请你将数组的内容改为”i am a student”....

C语言学习笔记之格式化I/O(scanf函数、printf函数)

1、printf()函数 1.1 函数原型 //若输出成功,则返回输出的字符数;若输出出错,返回负数 int printf(const char *format, item1, item2, ...)...

程序猿之--C语言细节13(二维数组和指针,&*a[i][0]的理解,数组1[e]和e[1]很可能你没见过)

主要内容:二维数组和指针,&*a[i][0]的理解 #include #define NUM_ROWS 10 #define NUM_COLS 10 int main(int argc, cha...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C语言优先级和(i++)+(i++)与(++i)+(++i)
举报原因:
原因补充:

(最多只允许输入30个字)