++i 和 i++ 的理解

原创 2016年08月30日 20:47:46

1.C语言为什么要使用++运算符呢? 

   C语言从Ken Thompson早期的B语言中继承了++和--。Thompson创造这类运算符是因为他的B语言编译器可以对++i产生比i = i + 1更简洁的翻译。这些运算符已经成为C语言根生蒂固的一部分,但是对于今天的编译器来说,使用++和--运算符不会使编译后的程序变得更短小或更快,继续使用这些运算符是因为他们非常简洁和便利。

2.运算符优先级表格:


3.++i 和 i++ 具体实现方法:

1> ++i是先增加后引用,先让i + 1,后在i所在的表达式中使用i的新值。

    number = ++i;  等价于:  i = i + 1; number = i;

2> i++是先使用后增加,先让i所在的表达式使用i的值,后让i + 1。

    number = i++;  等价于:temp = i; number = temp; i = temp +1;

4.++i 和 i++ 的使用实例分析。

最后输出的a和b的值分析。


#include <stdio.h>

int main(int argc, const char * argv[]) {

    int  a,b;

    for (a = 0, b = 0; a < 5; a++) {

        b += a++;

    }

    printf("a = %d\nb = %d\n",a,b);

    return 0;

}

  1> 首先先来明确一个观点:a++是先使用再加1,而++a是先加1后再操作。因此,顺序的读程序,开始进入for循环。
  2> 第一次进入时a的初始值是0,b的初始值也是0。这时的a++并没有在本次语句中起到加1的作用,而是要在本次操作结束后再起作用,也就是在第一次循环完全结束后。进入循环体看,b += a++;这时由于这里的是a++(需要先操作后加1),所以,b的值理所当然是0了,而在本句结束后a的值就进行了加1操作,在本次循环结束时又进行了一次加1操作,所以本次循环结束后a=2,b=0。
  3> 第二次进入时a的初始值是2,b的初始值是0。同理分析,在b += a++;后b的值为2了,而a的值也由于两次a++变为了4。所以,本次循环结束后a=4,b=2。
  4> 第三次进入时a的初始值是4,b的初始值是2。同理分析,在b += a++;后b的值由于经过原来的值与i当前的值相加后变成了6,而a的值同样是在最后加了两个1。所以在本次循环结束后a=6,b=6。
  5> 第四次准备进入循环时,发现a的值已经比5大了。因此,程序终止。最后a的值为6,b的值也为6。


5.常见使用易错分析。

1> 在使用后缀形式的++和--时,(后缀形式:i++,i--)何时执行自增或自减操作?

    C语言标准引入了“顺序点”的概念,并且指出“应该在前一个顺序点和下一个顺序点之间对存储的操作数的值进行更新”。在C语言中有多种不同类型的顺序点,表达式语句的末尾是其中的一种,在表达式语句的末尾,该语句中的所有自增和自减操作都必须执行完毕,否则不能进入下一条语句。(例:number = i++; 这句代码  要先执行完:temp = i; number = temp; i = temp +1; 才会执行下一句代码。)

2>自增运算符不能用于表达式。

例:如果a = 0;b = 0;计算(a + b)++ 这个表达式的值。

  举个例子让你理解这个题目 假设a = 1,b = 2;那么(a + b)之后等于3,因此3是一个常量,不再是变量,因此是错误的,也就是说++是不能对常量进行操作的,也就是不能这样使用5++。

  其次,a++是与a = a + 1是等效的,也就是说执行a++后,变量a的值本来是1,但执行后就变为2了,而常量的值是不能改变的,也就是说执行5++之后,不可能把5变为6,因此常量不能使用++运算符操作。

  所以,在这里不能用 j = ++i++ 来判断前缀++和后缀++的优先级是错误的,因为不管是前缀++还是后缀++的优先级高,总有一个是对表达式操作的,也就是对常量操作的。


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Java中i=i++;运算结果

今天看到一个题,结果和原本想的不太一样,也有些意思,同时也深入地考虑到更多情况。 原本的题大体如下, 以下程序的输出结果是什么? Class Test{   public static voi...

面试题【1】:i++是否原子操作?并解释为什么?

不是原子操作。理由: 1.i++分为三个阶段: 内存到寄存器 寄存器自增 写回内存 这三个阶段中间都可以被中断分离开.  2.++i首先要看编译器是怎么编译的, 某些编译器比如VC在非优...

Eclipse查看Java源码的方式

按Ctrl 鼠标左键点击方法名,这就是在Eclipse查看源码的方法。 问题是一般情况下点击了没反应,就傻逼了。 通过下面几个步骤可以完美的解决这个问题,可以看到Java的源码实现。 1.点 “...

【java】:如何自己构造一个package(包)

前言楼主对于JAVA这块不是很熟,因此今天特地去学习了相关的知识,然后觉得挺有意思,于是写出来和大家分享正文首先大家要明白的是,包是一种什么东西? 大家经常会进行的一个操作是import java...

深入理解Android 卷I

  • 2015年02月11日 20:42
  • 33.68MB
  • 下载

深入理解Android之I

  • 2012年12月02日 10:48
  • 3.86MB
  • 下载

“I帧”和“帧间距”等的理解

1)  30 # i intervals  // I 帧间距 2)30 # idr intervals// idr帧间距 3)   0 # b frame number betwee...

深入理解Android 卷I part2

  • 2013年10月30日 10:50
  • 10MB
  • 下载

我对linux理解之i2c 二

我们下面开始分析i2c的通信,即读写过程。 我们先看读函数,对应i2c core中的i2c_master_recv: int i2c_master_recv(struct i2c_client *...
  • sadamoo
  • sadamoo
  • 2012年09月11日 17:26
  • 6786
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:++i 和 i++ 的理解
举报原因:
原因补充:

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