C语言自增自減问题总结

在程序设计中,经常遇到“i=i+1”和“i=i-1”这两种极为常用的操作。C语言为这种操作提供了两个更为简洁的运算符,即++和--,分别叫做自增运算符和自减运算符。它们是单目运算符,是从右向左结合的算术运算符。学习和应用这两个运算符时应注意以下几点:

我将自增自减运算符和变量结合在一下的表达式称为自增自减表达式,如x++,--I等。通常情况下就有以下的结论:

1‘’前缀表达式:++x, --x; 其中x表示变量名,先完成变量的自增自减1运算,再用x的值作为表达式的值;即“先变后用”,也就是变量的值先变,再用变量的值参与运算。

2、后缀表达式:x++, x--;  先用x的当前值作为表达式的值,再进行自增自减1运算。即“先用后变”,也就是先用变量的值参与运算,变量的值再进行自增自减变化,。

如a=8; b=a++; c=++a; 其中赋给变量b的值为表达式(a++)的值,不应该理解为a的值,则b=8, c=10;

3、自增、自减运算只能用于单个变量,只要是标准类型的变量,不管是整型、实型,还是字符型变量等,但不能用于表达式或常量。如:++(a+b), 与5++,  const int N=0; N++; 等都是错误的。 而i+++j++、++i+(++j)、++a+b++、++array[--j];等,这些都是合法的。

4、再说结合性与结合方向

编译器对程序编译时,从左到右尽可能多地将字符组合成一个运算符或标识符,因此i+++j++等效于(i++)+(j++),两个“++”作用的对象都是变量,这是合法的;而++i+++j等效于++(i++)+j,第1个“++”作用的对象是表达式“i++”,这是不允许的。

自增自减运算符是单目运算符,其结合性是从右到左。表达式k=-i++等效于k=(-i)++还是k=-(i++)?。因为负号也是单目运算符,因此,上式从右到左结合,等效于k=-(i++);若i=5,则表达式k=-i++运算之后k的值为-5,i的值为6。此赋值表达式的值即为所赋的值-5。不要因为k=-i++等效于k=-(i++)就先做“++”运算!这里采用的是“先用后变”,即先拿出i的值做负号“-”运算,把这个值赋给变量k之后变量i才自增。

5、注意运算符的副作用

C语言允许在一个表达式中使用一个以上的赋值类运算,包括赋值运算符、自增运算符、自减运算符等。这种灵活性使程序简洁,但同时也会引起副作用。这种副作用主要表现在:使程序费解,并易于发生误解或错误。例如,当i=3时,表达式(i++)+(i++)+(i++)的值为多少,各种教材说法不统一。对于这种情况,为了增强程序的可读性与可移植性,在一个表达式中,就应该用简单的自增与自减运算,不用对同一变量进行多次自增自减运算的表达式,否则,其他人可能看不懂,换个运行环境也可能是不同的结果。我相信,在考试试题中也是不会出现象这种有不同结果的试题的,请读者放心。当然,为了丰富知识,了解一下这些内容也是必要的。

以下内容是经查阅资料所得:用各种表达式上机测试,给出VC++环境下连续自增(自减)运算规则:

1、 在一般表达式中和在函数参数中计算的结果相同(这一点与Turbo C环境不同);

2、 后缀:同表达式中Turbo C的情况相同:先统一取值后依次自增,如:

int a,i=5; a=i+++i+++i++; a=15, i=8.

3、 前缀:前两个自增同Turbo C,即依次自增后统一取值,后面的每个自增后即取值,如:

int a, i=5; a= ++i +(++i)+(++i); a=22, i=8.

4、 前后缀混合的情况:

(1) 一般情况:表达式中自左向右计算,参数自右向左运算。前缀自增后取值;后缀(或变量)取值依其所处位置而定,有连续多个将统一取值,其自增在语句结束前进行。

(2) 前后缀各有一个的情况:设int i=5; 由于i++*++i应满足交换率与++i*i++相同,规定按后者计算故为36。实验2内容4:int i=5; printf("%d,%d\n", --i, i++*++i ); 打印5,36。

(3) 若i++或++i或两者有多于一个的情况:++i有两个以上在一起时最左边的连续自增同3、,其余每个自增后取值,如:int i=5;

printf("%d\n%d\n",--i,(++i)+(i++)+(i++)+(++i)); 打印6和25

printf("%d\n%d\n",--i,(++i)+(++i)+(++i)+(++i)+(i++)); 打印8和40

printf("%d\n%d\n",--i,(++i)+(++i)+(++i)+i+(++i)+(++ i)); 打印9和49

(4) 函数参数中有括号时,括号参数优先计算,其余参数仍自右向左计算,如:

int i=9,j=8; printf("%d %d\n", (++i, j--), ++i); 打印8 11

printf("%d %d %d\n", (++i, j--), ++i, i); 打印8 11 10

(5) 最后i的值等于原值加总自增次数减自减的次数.

克服这类副作用的方法是,尽量把程序写得易懂一些,即将费解处分解成若干个语句。如:k=i+++j:可写成k=i+j:i++:而类似(i++)+(i++)+(i++)这类连续自增、自减的运算最好不要使用,以避免疑团的出现,同时也可减少程序出错的可性能。

最后感谢为了得到正确结果而花较多时间去上机实践的人们,祝你幸福快乐!

转:C语言自增自減问题总结的更多相关文章

  1. Python进阶----数据库的基础,关系型数据库与非关系型数据库(No SQL:not only sql),mysql数据库语言基础(增删改查,权限设定)

    day37 一丶Python进阶----数据库的基础,mysql数据库语言基础(增删改查,权限设定) 什么是数据库:    简称:DataBase ---->DB    数据库即存放数据的仓库, ...

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

    转自:http://bbs.csdn.net/topics/330189207 C语言的自增++,自减--运算符对于初学者来说一直都是个难题,甚至很多老手也会产生困惑,最近我在网上看到一个问题:#in ...

  3. c#语言自增自减运算符深入剖析

    C语言的++和--对于初学者来说一直都是难题,甚至很多老手也会产生疑惑; 最大的问题在于 ++可以放在变量后面,也可以放在前面; 如 i++; ++i; 自减运算符与++原理一样,只是变量变价为减而已 ...

  4. C/C++编程笔记:C语言自增(++)和自减(--)运算符详解,笔记分享

    一个整数类型的变量自身加 1 可以这样写: a = a + 1; 或者 a += 1; 不过,C语言还支持另外一种更加简洁的写法,就是: a++; 或者 ++a; 这种写法叫做自加或自增,意思很明确, ...

  5. SQL语言的增删改查

    select(查), update(改), delete(删), insert into(增)   select * from table_name 获取表中所有字段 select id, name, ...

  6. SQL数据库—<1>SQL语言

    关系数据库.SQL语言简单.学习软件介绍 SQL:Structured Query Language 结构化查询语言 数据库分为:层次型,网状型,关系型. 关系型数据库:是一个二维表的集合,可以用来存 ...

  7. c语言:函数的递归调用

    c语言可以将代码模块化,这是其很重要的一个特性. 说道代码模块化,我们很自然的就会联想到函数.而函数中,比较难的一个知识点就是函数的递归调用. 值得注意的是,函数的递归调用在现实工作并不是很常用,但是 ...

  8. 18 11 04 初用单片机 c语言学习

    ---恢复内容开始--- 1 作为单片机使用的的 c 语言学习 ++ 增位运算符 在原有基础上加一 -- 相同 由于单片机只有 ~ 取反 & 两个 参数里有没有 | 两个 参数里有没有 ^ 两 ...

  9. MySQL之JDBC编程增删改查

    MySQL之JDBC 一.JDBC是什么 Java DatabaseConnectivity (java语言连接数据库) 二.JDBC的本质 JDBC是SUN公司制定的一套接口(interface). ...

随机推荐

  1. Leetcode1.两数之和——简洁易懂

    > 简洁易懂讲清原理,讲不清你来打我~ 输入一个数组和一个整数,从数组中找到两个元素和为这个整数,输出下标![在这里插入图片描述](https://img-blog.csdnimg.cn/img ...

  2. Geoserver通过ajax跨域访问服务数据的方法(含用户名密码认证的配置方式)

    Goeserver数据有两种,一种需进行用户密码的权限认证,一种无须用户密码.对于网上跨域访问Geoserver数据的种种方法,对这2种数据并非通用. 笔者将Geoserver官方下载的Geoserv ...

  3. OVERLAPPED 结构

    typedef struct _OVERLAPPED { ULONG_PTR Internal; ULONG_PTR InternalHigh; union { struct { DWORD Offs ...

  4. lwIP(Light Weight IP)协议

    信号量 信号量结构体:struct sys_semt struct _sys_sem { void *sem; };  err_t sys_sem_new(sys_sem_t *sem, u8_t c ...

  5. CentOS7下OpenLDAP部署

    OpenLDAP作为开源的LDAP服务,可用于搭建统一认证平台,在很多企业内部应用比较广泛,本文将介绍在CentOS7下OpenLDAP的部署. 环境: CentOS 7.4 OpenLDAP 2.4 ...

  6. SourceTree 3.1.3版本跳过注册

    1.进入文件夹 %LocalAppData%\Atlassian\SourceTree\ 找到SourceTree的目录 2.里面添加一个json文件 accounts.json 内容如下: [{&q ...

  7. sql server 查看数据库配置等信息(字符集,编码格式,版本号...)

    select SERVERPROPERTY(N'edition') as Edition --数据版本,如企业版.开发版等,SERVERPROPERTY(N'collation') as Collat ...

  8. FastAPI:一个测试人员视角的教程

    前言 教程肯定谈不上了,主要还是就自己的理解分享内容而已 内容是连官方文档的基础教程都没涵盖起的 建议直接看官方文档 以个人视角来分享,希望各位通过这个可以写接口了 需要自取 完整视频链接:https ...

  9. Pytorch Torchvision Transform

    Torchvision.Transforms Transforms包含常用图像转换操作.可以使用Compose将它们链接在一起. 此外,还有torchvision.transforms.functio ...

  10. 快速上手 Rook,入门云原生存储编排

    Rook 是一个开源 cloud-native storage orchestrator(云原生存储编排器),为各种存储解决方案提供平台.框架和支持,以与云原生环境进行原生集成. Rook 将存储软件 ...