为自增(++)自减(--)运算符正名
学过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语言指南》(李忠,电子工业出版社)
为自增(++)自减(--)运算符正名相关推荐
- 关于printf()与自增自减运算符结和问题
1.问题描述: #include<stdio.h> int main() {int i=3;printf("%d %d %d %d %d",i++,++i,++i,i+ ...
- c语言自增自减5运算符详解,巧用C语言中的自增自减运算符
黄建琼 摘要:自增自减运算符在C语言的编程过程中经常用到,具有重要的作用,而灵活使用自增自减运算符则是个难点.该文从几个例子入手,观察运行的结果,对结果进行分析,最后得出结论.以期能使初学者避重就轻, ...
- 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 ...
- C语言系列之自增自减运算符的用法(二)
运算符中最难理解的有自增自减运算符的使用方法,下面我将简单总结一下他们的使用方法 我们知道,C语言运行是由右向左运行的 下面我们来看一个例子 当i等于3的时候 j=++i; 由上面可知,C语言是由右向 ...
- C语言连续自动自加怎么表示,为什么不建议在C语言中连续使用自增自减运算符...
相信很多coder在学习C语言(包括C++)的过程中都听说过这样的建议:慎用自增自减运算符. 这是因为,在函数参数或者表达式中多次调用自增自减运算符很可能产生"不可预知的结果".究 ...
- c语言3u减1,C语言的自增自减运算符及应用
在C语言中,经常使用自增自减运算符.本文结合实例,对C语言中自增自减运算符的应用技巧进行了分析. 维普资讯 http://doc.xuehai.net J u a fAn a gT a h r olg ...
- c语言中自增自减运算符,C语言中自增自减运算符的深入剖析
C语言中自增自减运算符的深入剖析 李文广 李俊荣 赵妍 . (1.沧州职业技术学院,2沧州工贸学校) [摘要]本文从多方面对自增自减运算符分析.讲解,以便让初学者 能够清晰自增自减运算符的运算规律,学 ...
- 学透Java自增(++)自减(--)运算符,看这一篇就够了!
三句重中之重的重点: 1.无论是前缀形式还是后缀形式,自增自减运算符的优先级要高于赋值运算符. 2.当一条语句中仅有++或--操作时,前缀形式与后缀形式的运算符没有任何区别. 3.前缀形式的运算规则可 ...
- Java 自增自减运算符
//自增自减运算符 public class ZZZJ {public static void main(String[] args) {//定义变量int i = 10;//System.out.p ...
- c语言:自增自减运算符的操作详解
博主在回忆c语言的基本知识时,突然发现自增自减运算符(--.++)这个知识点有些模糊不清,故博主为了给同为小白的同学们提供一些经验,特写下这篇文章. 首先,自增自减运算符共有两种操作方式. 比如,我先 ...
最新文章
- KV结构的集合,在处理null值的存储上有细微的区别,下列哪些说法是正确的
- 冲刺周期二--站立会议01
- python详细安装教程环境配置-python3.6环境安装+pip环境配置教程图文详解
- ASP.NET生命周期详解(转)
- VALID SAME
- 2021夏季每日一题 【week5 完结】
- Show Attend and Tell的词表
- 计算机二级web题目(5)--js(Javascript)基础
- 《Linux内核设计与实现》读书笔记 - 目录 (完结)【转】
- 常用工具下载及在线地址
- seata分布式事务原理_分布式事务 Seata 及其三种模式详解
- SLAM--单目尺度漂移(相似变换群Sim3)
- 松下服务器报警13参数修改,新版松下伺服发生故障报警代码一览及对策.doc
- 微机原理与接口技术期末考试总结
- C++ 函数的声明和定义
- php类的定义与实例化方法
- Linux搭建 我的世界(Minecraft) 1.17.1版 服务器教程
- Unity3D中实现人物的第一人称视角
- 对话式AI系列:中关村科金领域知识中台建设方法论与实践
- 后端文件流在浏览器pdf预览