自增自减运算法的深入理解

例二:

int i=3;
  int j=4;
  int a = i++ + i++;
  int b = ++j + ++j;
  printf("%d, %d\n", a, b);

问题又来了,i++ + i++是先自增一次,相加,再自增,然后赋值呢,还是先相加赋值然后自增两次呢。另外,++j又将如何表现呢?

结果是:6,12

这下明白了,原来 i++的理解应该是执行完整个表达式的其他操作后,然后才自增,所以例子中的a=3+3=6;而后i再自增2次,i=5;相反,++j是先自增然后再参加其它运算,所以b=6+6=12。

到此,是否就彻底明了了呢?然后回到引子中的问题:

例三:

int i=3;
  int j=4;
  int a = i++ + i++ + i++;
  int b = ++j + ++j + ++j;
  printf("%d, %d\n", a, b);

有人可能会说,这很简单,我全明白了:a=3+3+3=9,i=6,b=5+5+5=15,j=5。真的是这样吗?

结果却是:9,19

这下可好,又糊涂了。对于a = i++ + i++ + i++;我们已经没有疑问了,++后置就是执行完整个表达式的其他操作后,然后才自增,上例中也得到了验证,但 b = ++j + ++j + ++j;又该如何理解呢?

原理表达式中除了预算法本身的优先级外,还有一个结合性问题。在++j + ++j + ++j;中,因为存在两个同级的+运算,根据+运算符的左结合性,在编译时,其实是先处理前面的(++j + ++j)这部分,然后再将此结果再和++j相加。具体过程参见汇编代码:

int b = ++j + ++j + ++j;
0040B7DD mov ecx,dword ptr [ebp-8]
0040B7E0 add ecx,1
0040B7E3 mov dword ptr [ebp-8],ecx // 第一个++j
0040B7E6 mov edx,dword ptr [ebp-8]
0040B7E9 add edx,1
0040B7EC mov dword ptr [ebp-8],edx // 第二个++j
0040B7EF mov eax,dword ptr [ebp-8]
0040B7F2 add eax,dword ptr [ebp-8] // ++j + ++j  
0040B7F5 mov ecx,dword ptr [ebp-8]
0040B7F8 add ecx,1
0040B7FB mov dword ptr [ebp-8],ecx // 第三个++j
0040B7FE add eax,dword ptr [ebp-8] // ++j + ++j + ++j
0040B801 mov dword ptr [ebp-10h],eax // 赋值给b

另外我们看看a = i++ + i++ + i++;的汇编代码:

int a = i++ + i++ + i++;
0040B7B6 mov eax,dword ptr [ebp-4]
0040B7B9 add eax,dword ptr [ebp-4] // i+i
0040B7BC add eax,dword ptr [ebp-4] // i+i+i
0040B7BF mov dword ptr [ebp-0Ch],eax // 赋值给a
0040B7C2 mov ecx,dword ptr [ebp-4]
0040B7C5 add ecx,1
0040B7C8 mov dword ptr [ebp-4],ecx // 第一次i++
0040B7CB mov edx,dword ptr [ebp-4]
0040B7CE add edx,1
0040B7D1 mov dword ptr [ebp-4],edx // 第二次i++
0040B7D4 mov eax,dword ptr [ebp-4]
0040B7D7 add eax,1
0040B7DA mov dword ptr [ebp-4],eax // 第三次i++

果然不出所料。到此,++运算符前置后置的问题应该彻底解决了。

例四:

int i=1;
  int j=1;
  int a = i++ + i++ + i++ + i++ + i++ + i++ + i++; // 七个
  int b = ++j + ++j + ++j + ++j + ++j + ++j + ++j;
  printf("%d, %d\n", a, b);
  printf("%d, %d\n", i, j);

规则就是规则,咱的计算机可不是黑客帝国的母体,总是要遵循它的

a = 1+1+1+1+1+1+1 = 7, i=8
b = 3+3+4+5+6+7+8 = 36, j=8

转自:
http://www.cnblogs.com/E-star/archive/2012/09/18/2691507.html

自增自减运算法的深入理解,布布扣,bubuko.com

时间: 2024-10-20 08:04:59

自增自减运算法的深入理解的相关文章

java中自增自减运算与c中自增自减的区别

今天看到java面试宝典里面有一道题目是这样的: 答案是0,我开始也有疑问,后来看到后面说到java的中间缓存变量,后来到网上查了查,终于理解了,是什么意思了.请看下面的代码和解释: package com.wj.demo; public class Test1 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int j=0; for(int i=

JavaScript自增自减运算

运算符 i++  i - - ++i - - i 解读 先赋值,再自增 先赋值,再自减 先自增,后赋值 先自减,后赋值 表达式 a = ++i a = i - - a = i++ a = i - - 表达式等价于 a = i ; i = i + 1; a = i;i =i - 1 i = i + 1; a = i; i = i - 1;a = i

Ex007 自增/自减运算

1 #include <stdio.h> 2 main() 3 { 4 int i=10; 5 printf("%d\n",++i); 6 printf("%d\n",--i); 7 printf("%d\n",i++); 8 printf("%d\n",i--); 9 printf("%d\n",-i++); 10 printf("%d\n",-i--); 11 getch

[转]C语言中自增自减运算符教学探究-中国论文网

摘要:C语言教学中,自增自减运算符运用得非常广泛,且具有一定的使用技巧和难度.在诸多运算符中,自增自减运算符是学生最难理解和最易出错的运算符.对自增自减运算符的功能和具体应用进行探究,以期为提高C语言教学效果提供帮助.中国论文网 http://www.xzbu.com/8/view-3865031.htm 关键词:C语言:自增自减运算符:教学效果 中图分类号:G434文献标识码:A文章编号:1672-7800(2012)012-0188-02 0引言 C语言编程设计中,若合理使用自增自减运算符,

java自增自减运算符

除了这+ - * / % 这5个算术运算符之外其实还有2种 ++ - - 这两个也可以属于算术运算符.他是自增自减运算的,例如:int i = 10; i++; i- - 或 ++i - -i但是这2个比较特殊,他有先运算和后运算一说.++ - -符号在后面的为后运算,++ - -符号在前面的为先运算例如:i++ i- - 这为后运算,++i - -i这为先运算. ++ - - 他是一个缩写的方式,融合了2句代码的缩写. 例如:int i = 100; int a = i; i = i+1; 意

编程题:自增运算与自减运算的运用

#include<stdio.h> void main() {int a1,a2,a3,a4,b1,b2,b3,b4; a1=a2=a3=a4=10; b1=(a1++)+(a1++)+(a1++); b2=(++a2)+(++a2)+(++a2); b3=(a3--)+(a3--)+(a3--); b4=(--a4)+(--a4)+(--a4); printf("a1=%d,a2=%d,b1=%d,b2=%d\n",a1,a2,b1,b2); printf("a

黑马程序员————C语言基础语法二(算数运算、赋值运算符、自增自减、sizeof、关系运算、逻辑运算、三目运算符、选择结构、循环结构)

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 第一讲  算数运算 C语言一共有34种运算符,包括了常见的加减乘除运算 1.加法运算+ 除开能做加法运算,还能表示正号:+5.+90 2.减法运算- 除开能做减法运算,还能表示符号:-10.-29 3.乘法运算* 注意符号,不是x,而是* 4.除法运算/ 注意符号,不是÷,也不是\,而是/ 整数除于整数,还是整数.1/2的值是0,这个并不是二分之一 5.取余运算% 什么是取余:两个整数相除之后

【转】 C语言自增自减运算符深入剖析

转自:http://bbs.csdn.net/topics/330189207 C语言的自增++,自减--运算符对于初学者来说一直都是个难题,甚至很多老手也会产生困惑,最近我在网上看到一个问题:#include <stdio.h> void main()  /*主函数*/ { int a,b,c,d;  a=5; b=5;  c=(a++)+(a++)+(a++);  d=(++b)+(++b)+(++b);  printf("a=%d,b=%d,c=%d,d=%d\n",

运算符(赋值、自增自减)、表达式、语句、优先级表

赋值运算符 赋值运算符左边的项目必须是一个变量的名字. 例:2002 = BMW:错误 1.乘除运算符高于加减运算符,运算符优先级相同由左向右. 2.赋值运算符优先级仅高于逗号运算符,结合方向从右到左. 注意:赋值运算符.条件运算符与单目运算符运算顺序从右到左,其他运算符从左到右. ++ 1.int a = 1; int b =2; b+a++==3,即先运算再加a=2,b=2; b+(++a)==4;即先加再运算a=2,b=2 b+++a==3;即(b++)+a=3,a=1,b=3; int