转:C语言自增自減问题总结
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语言自增自減问题总结的更多相关文章
- Python进阶----数据库的基础,关系型数据库与非关系型数据库(No SQL:not only sql),mysql数据库语言基础(增删改查,权限设定)
day37 一丶Python进阶----数据库的基础,mysql数据库语言基础(增删改查,权限设定) 什么是数据库: 简称:DataBase ---->DB 数据库即存放数据的仓库, ...
- 【转】 C语言自增自减运算符深入剖析
转自:http://bbs.csdn.net/topics/330189207 C语言的自增++,自减--运算符对于初学者来说一直都是个难题,甚至很多老手也会产生困惑,最近我在网上看到一个问题:#in ...
- c#语言自增自减运算符深入剖析
C语言的++和--对于初学者来说一直都是难题,甚至很多老手也会产生疑惑; 最大的问题在于 ++可以放在变量后面,也可以放在前面; 如 i++; ++i; 自减运算符与++原理一样,只是变量变价为减而已 ...
- C/C++编程笔记:C语言自增(++)和自减(--)运算符详解,笔记分享
一个整数类型的变量自身加 1 可以这样写: a = a + 1; 或者 a += 1; 不过,C语言还支持另外一种更加简洁的写法,就是: a++; 或者 ++a; 这种写法叫做自加或自增,意思很明确, ...
- SQL语言的增删改查
select(查), update(改), delete(删), insert into(增) select * from table_name 获取表中所有字段 select id, name, ...
- SQL数据库—<1>SQL语言
关系数据库.SQL语言简单.学习软件介绍 SQL:Structured Query Language 结构化查询语言 数据库分为:层次型,网状型,关系型. 关系型数据库:是一个二维表的集合,可以用来存 ...
- c语言:函数的递归调用
c语言可以将代码模块化,这是其很重要的一个特性. 说道代码模块化,我们很自然的就会联想到函数.而函数中,比较难的一个知识点就是函数的递归调用. 值得注意的是,函数的递归调用在现实工作并不是很常用,但是 ...
- 18 11 04 初用单片机 c语言学习
---恢复内容开始--- 1 作为单片机使用的的 c 语言学习 ++ 增位运算符 在原有基础上加一 -- 相同 由于单片机只有 ~ 取反 & 两个 参数里有没有 | 两个 参数里有没有 ^ 两 ...
- MySQL之JDBC编程增删改查
MySQL之JDBC 一.JDBC是什么 Java DatabaseConnectivity (java语言连接数据库) 二.JDBC的本质 JDBC是SUN公司制定的一套接口(interface). ...
随机推荐
- Python Unittest简明教程
1 概述 单元测试框架是一种软件测试方法,通过来测试源代码中的各个单元,例如类,方法等,以确定它们是否符合要求.直观上来说,可以将单元视为最小的可测试部分.单元测试是程序员在开发过程中创建的短代码片段 ...
- MySql存储过程的创建与使用及在thinkphp中如何调用笔记
学习sql的存储过程,笔记总结如下: MySQL默认将分号,即";"作为语句的分隔符.如果是这样的话,则一个存储过程将很难正常创建,因为它的BEGIN和END之间可以是任意数量的S ...
- 免杀mimikatz
mimikatz源码 下载地址https://github.com/gentilkiwi/mimikatz/releases/tag/2.2.0-20210709 使用vs2019打开工程mimik ...
- 透视RPC协议:SOFA-BOLT协议源码分析
前提 最近在看Netty相关的资料,刚好SOFA-BOLT是一个比较成熟的Netty自定义协议栈实现,于是决定研读SOFA-BOLT的源码,详细分析其协议的组成,简单分析其客户端和服务端的源码实现. ...
- 手写Pascal解释器(三)
目录 一.part7 抽象语法树和具体语法树(解析树) 代码实现 二.part8 一.part7 资料来源:https://ruslanspivak.com/lsbasi-part7/ 看作者博客的标 ...
- Vulhub-DC-1靶场
前言: DC-1靶场是Vulhub系一款渗透测试的实战靶场,拥有五个Flag.本篇博客讲述了如何拿去这五个Flag,并详细描述其中的注意点. 实验环境: 虚拟机环境:virtualbox 虚拟机1:D ...
- git的实用命令(撤回,合并)
前言 在用开发项目的时候,经常会写着写着会发现写错的时候,人生没有后悔药,但是git有啊,大不了从头再来嘛. git的一些撤销操作 代码还没有存到暂存区 当我们修改了一个文件,还没有执行git add ...
- EL表达式和JSTL标签
什么是 EL 表达式,EL 表达式的作用? EL 表达式的全称是:Expression Language.是表达式语言. EL 表达式的什么作用:EL 表达式主要是代替 jsp 页面中的表达式脚本在 ...
- 将vim打造成Java IDE
需要的插件列表: Taglist Conque Shell FuzzyFinder NERDTree javaComplete 其他选项: JavaKit exVim winmanager (Depr ...
- Python语言系列-05-模块和包
自定义模块 #!/usr/bin/env python3 # author:Alnk(李成果) # 为什么要有模块?(内置函数不够用) # 和操作系统打交道 # 和python解释器打交道 # 和时间 ...