学过C语言的朋友,相信你对“++i”,“- -i”,“i++”,“i- -”这样的表达式并不陌生,可是你真正明白其中的含义吗?

我发现在网上,充斥着对它们的误解,或者说似是而非的,似懂非懂的理解。我先举例一二。
一个来自于网上的例子(代码排版我修改了一下,这样符合我的阅读习惯):

#include <stdio.h>int main(void)
{int a = 10;int b = 20;int c = 30;int d = 40;int a1,b1,c1,d1;a1 = ++a;b1 = b++;c1 = --c;d1 = d--;printf("a=%d, a1=%d\n", a, a1);printf("b=%d, b1=%d\n", b, b1);printf("c=%d, c1=%d\n", c, c1);printf("d=%d, d1=%d\n", d, d1);return 0;
}

输出结果:
a=11, a1=11
b=21, b1=20
c=29, c1=29
d=39, d1=40
文中是这样解释的:

a、b、c、d 的输出结果相信大家没有疑问,下面重点分析a1、b1、c1、d1:

1) 对于a1=++a,先执行++a,结果为11,再将11赋值给a1,所以a1的最终值为11。而a经过自增,最终的值也为11。

2) 对于b1=b++,b的值并不会立马加1,而是先把b原来的值交给b1,然后再加1。b原来的值为20,所以b1的值也就为20。而b经过自增,最终值为21。

3) 对于c1=- -c,先执行- -c,结果为29,再将29赋值给c1,所以c1的最终值为29。而c经过自减,最终的值也为29。

4) 对于d1=d- -,d的值并不会立马减1,而是先把d原来的值交给d1,然后再减1。d原来的值为40,所以d1的值也就为40。而d经过自减,最终值为39。

可以看出:
a1=++a; 会先进行自增操作,再进行赋值操作;
而b1=b++; 会先进行赋值操作,再进行自增操作。
c1=- -c; 和 d1=d- -; 也是如此。

网上还有这样的理解:

如果++或- -放在操作数前面就先进行自增或自减,再进行其他运算;
如果++或- -放在操作数后面就先进行其他运算,再进行自增或自减。

我觉得,虽然按照上文的解释可以分析出正确的答案,但是不够“专业”。

请看比较专业的解释(以++为例):
后缀递增

一个基本表达式(用E表示)的后面加上运算符“++”,就可以构成后缀递增表达式。 例如:

int i=0;
int j=0;
j = i++; //合法
int *p = &i;
(*p)++; //合法

后缀递增表达式的结果不是左值,它的值是E所指示的对象在递增操作前的原值,而不是递增后的新值;

后缀递增是具有副作用的表达式,这个副作用会修改E所指示的对象,将它的存储值变为表达式E+1的值;

E要求是实数类型或者指针类型,而且必须是可以修改的左值,所以像“250++”这样的表达式是非法的;

后缀递增表达式的结果类型和E的类型相同。

特别要指出:后缀++运算符的值的计算和它的副作用有确定的前序和后序关系,也就是说是先计算和得到后缀运算符++的值(这也是整个后缀递增表达式的值),再修改其操作数的存储值。

int i=0;
int j=1;
j = i++;

对于j = i++;
是要把i++这个表达式的值赋值给j; 而i++这个表达式的值是i所指示的对象在递增操作前的原值(也就是0),所以这条语句执行后,j=0;
同时,i++这个表达式是有副作用的,副作用就是i的存储值增加1,于是i变为1;

需要强调的是,i++这个表达式的值的计算和i的递增是有先后顺序的:先计算i++这个表达式的值 (=0),再递增i (递增后i=1).

前缀递增
运算符++加上一个表达式E,即可构成前缀递增表达式。
例如:

int a[2] = {3, 4};
int *p = a;
++a[0]; //合法
++p;   //合法

前缀递增表达式的结果不是左值,它的值是E所指示的对象在递增操作后的新值,即它在数值上等于表达式E+1的值;

前缀递增是具有副作用的表达式,这个副作用会修改E所指示的对象,将它的存储值变为表达式E+1的值;

E要求是实数类型或者指针类型,而且必须是可以修改的左值,所以像++++i这样的表达式是非法的;

前缀递增表达式的结果类型和E的类型相同。

在语义上,前缀递增表达式++E等价于表达式E += 1;

(完)

参考资料:《标准C语言指南》(李忠,电子工业出版社)

为自增(++)自减(--)运算符正名相关推荐

  1. 关于printf()与自增自减运算符结和问题

    1.问题描述: #include<stdio.h> int main() {int i=3;printf("%d %d %d %d %d",i++,++i,++i,i+ ...

  2. c语言自增自减5运算符详解,巧用C语言中的自增自减运算符

    黄建琼 摘要:自增自减运算符在C语言的编程过程中经常用到,具有重要的作用,而灵活使用自增自减运算符则是个难点.该文从几个例子入手,观察运行的结果,对结果进行分析,最后得出结论.以期能使初学者避重就轻, ...

  3. c语言ll和 amp amp 优先级,关于C语言自增自减运算符的灵活使用.pdf

    DOI:10.3969/j.issn.1001-8972.2012.24.035 {int m=2,n: n=fun(m,++m): l?rintf("%d",n):} int f ...

  4. C语言系列之自增自减运算符的用法(二)

    运算符中最难理解的有自增自减运算符的使用方法,下面我将简单总结一下他们的使用方法 我们知道,C语言运行是由右向左运行的 下面我们来看一个例子 当i等于3的时候 j=++i; 由上面可知,C语言是由右向 ...

  5. C语言连续自动自加怎么表示,为什么不建议在C语言中连续使用自增自减运算符...

    相信很多coder在学习C语言(包括C++)的过程中都听说过这样的建议:慎用自增自减运算符. 这是因为,在函数参数或者表达式中多次调用自增自减运算符很可能产生"不可预知的结果".究 ...

  6. c语言3u减1,C语言的自增自减运算符及应用

    在C语言中,经常使用自增自减运算符.本文结合实例,对C语言中自增自减运算符的应用技巧进行了分析. 维普资讯 http://doc.xuehai.net J u a fAn a gT a h r olg ...

  7. c语言中自增自减运算符,C语言中自增自减运算符的深入剖析

    C语言中自增自减运算符的深入剖析 李文广 李俊荣 赵妍 . (1.沧州职业技术学院,2沧州工贸学校) [摘要]本文从多方面对自增自减运算符分析.讲解,以便让初学者 能够清晰自增自减运算符的运算规律,学 ...

  8. 学透Java自增(++)自减(--)运算符,看这一篇就够了!

    三句重中之重的重点: 1.无论是前缀形式还是后缀形式,自增自减运算符的优先级要高于赋值运算符. 2.当一条语句中仅有++或--操作时,前缀形式与后缀形式的运算符没有任何区别. 3.前缀形式的运算规则可 ...

  9. Java 自增自减运算符

    //自增自减运算符 public class ZZZJ {public static void main(String[] args) {//定义变量int i = 10;//System.out.p ...

  10. c语言:自增自减运算符的操作详解

    博主在回忆c语言的基本知识时,突然发现自增自减运算符(--.++)这个知识点有些模糊不清,故博主为了给同为小白的同学们提供一些经验,特写下这篇文章. 首先,自增自减运算符共有两种操作方式. 比如,我先 ...

最新文章

  1. KV结构的集合,在处理null值的存储上有细微的区别,下列哪些说法是正确的
  2. 冲刺周期二--站立会议01
  3. python详细安装教程环境配置-python3.6环境安装+pip环境配置教程图文详解
  4. ASP.NET生命周期详解(转)
  5. VALID SAME
  6. 2021夏季每日一题 【week5 完结】
  7. Show Attend and Tell的词表
  8. 计算机二级web题目(5)--js(Javascript)基础
  9. 《Linux内核设计与实现》读书笔记 - 目录 (完结)【转】
  10. 常用工具下载及在线地址
  11. seata分布式事务原理_分布式事务 Seata 及其三种模式详解
  12. SLAM--单目尺度漂移(相似变换群Sim3)
  13. 松下服务器报警13参数修改,新版松下伺服发生故障报警代码一览及对策.doc
  14. 微机原理与接口技术期末考试总结
  15. C++ 函数的声明和定义
  16. php类的定义与实例化方法
  17. Linux搭建 我的世界(Minecraft) 1.17.1版 服务器教程
  18. Unity3D中实现人物的第一人称视角
  19. 对话式AI系列:中关村科金领域知识中台建设方法论与实践
  20. 后端文件流在浏览器pdf预览

热门文章

  1. Java web学习(一)Servlet简介
  2. Ubuntu升级python版本
  3. BZOJ 1084: [SCOI2005]最大子矩阵【DP】
  4. $.ajax和$.load的区别
  5. WinForm 之 程序启动不显示主窗体
  6. Jmeter-获取响应结果中参数出现的次数
  7. C程序中常见的内存操作错误
  8. PHP -----上传文件
  9. iOS开发 贝塞尔曲线UIBezierPath(后记)
  10. CentOS 6.5系统安装配置图解教程(详细图文)