自增

(1)后缀:与Turbo C相同,在语句结束之前或者说分号之前才会执行自增。

(2)前缀:

前两个自增统一取值,后面的自增即为取值。

  int i=2,j;
  j=++i+(++i)+(++i);

j=4+4+5;

注意不能直接写j=++i+++i+++i;

否则会报错error C2105: '++' needs l-value;

因为++后面跟的还是+,必须要左值才能++;

    int i=2,j;
j=(i++)++;

如此也同样会报错error C2105: '++' needs l-value;

因为i++返回的是一个数值 ,而不是一个可赋值的变量(左值);

统一取值必须是指前两个并且必须是连在一起的,否则每一个都是自增即为取值。

    int i=,j;
j=++i+i+++(++i)+(++i);

j=3+3+4+5;

无论是int 还是 float都遵循这个规则。

(3)在乘法中的使用规则:

i++*++i自动识别为++i*i++;

    int i=,j1,j2;
j1=i++*++i;
i=;
j2=++i*i++;

j1=3*3;

j1==j2;

自减也是同样的。

在printf中,后缀自增也是在语句结束是才进行操作的。

    int i=;
printf("%d\n",i=i++);
i=;
printf("%d %d\n",i,i++);

结果都是2。

《裘宗燕:C/C++ 语言中的表达式求值》文章摘要:

另外,想要知道变量更新的值是否已经保存到了内存,需要注意顺序点在哪里;

C/C++语言定义(语言的参考手册)明确定义了顺序点的概念。顺序点位于:
1. 每个完整表达式结束时。完整表达式包括变量初始化表达式,表达式语句,return语句的表达式,以及条件、循环和switch语句的控制表达式(for头部有三个控制表达式);
2. 运算符 &&、||、?: 和逗号运算符的第一个运算对象计算之后;
3. 函数调用中对所有实际参数和函数名表达式(需要调用的函数也可能通过表达式描述)的求值完成之后(进入函数体之前)。

而且C/C++并没有对所有的运算顺序进行规定,而是交由编译器根据需要实现调整,从而得到效率更高的代码;

Java则有严格规定表达式求值顺序,但大部分程序设计语言实际上都才用了类似C/C++的规定。

“谁知道下面C语句给n赋什么值?”
m = 1; n = m++ +m++;
正确回答是:不知道!语言没有规定它应该算出什么,结果完全依赖具体系统在具体上下文中的具体处理。

其中牵涉到运算对象的求值顺序和变量修改的实现时刻问题。

评论区摘要:

②c99:
Annex J
J.1 Unspecified behavior:

— The order in which subexpressions are evaluated and the order in which side effects take place,

except as specified for the function-call (), &&, ||, ?:, and comma operators (6.5).
— The order in which the function designator(操作数指示符), arguments(实参), and subexpressions(子表达式) within the arguments are evaluated in a function call (6.5.2.2).
— The order in which the operands of an assignment operator(赋值运算符的操作数) are evaluated(被求值) (6.5.16).
........

J.2 Undefined behavior
— Between two sequence points(序列点/顺序点), an object is modified(修正) more than once, or is modified
and the prior value is read other than(除了) to determine the value to be stored (6.5).
......

④c++0x最终草案(FDIS )
ISO/IEC FDIS 14882 
N3290:
1.9 Program execution(执行)

15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual

expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution

of a program,unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed

consistently(一贯地)in different evaluations. —end note ] The value computations of the operands of

an operator are sequenced before the value computation of the result of the operator. If a side effect on a

scalar object(标量对象)is unsequenced relative to either another side effect on the same scalar object or

a value computation using the value of the same scalar object, the behavior is undefined.

[ Example:
void f(int, int);
void g(int i, int* v) {
i = v[i++]; // the behavior is undefined
i = 7, i++, i++; // i becomes 9
i = i++ + 1; // the behavior is undefined
i = i + 1; // the value of i is incremented(递增)
f(i = -1, i = -1); // the behavior is undefined
}
—end example ]
When calling a function (whether or not the function is inline(内联)[内联函数继承了宏定义的优点,也消除了它的缺点]),

every value computation and side effect associated with any argument expression, or with the postfix expression

designating(把...定名为) the called function, is sequenced before execution of every

expression or statement in the body of the called function. [ Note: Value computations and side effects

associated with different argument expressions are

unsequenced. —end note.]

Every evaluation in the calling function (including other function calls) that is not otherwise specifically

sequenced before or after the execution of the body

of the called function is indeterminately sequenced with respect to the execution of the called function.9 Several

contexts in C++ cause evaluation of a function call,even though no corresponding function call syntax appears i

n the translation unit.

[ Example: Evaluation of a new expression invokes(借助) one or more allocation and constructor functions; see 5.3.4.

For another example,invocation of a conversion function (12.3.2) can arise in contexts(上下文)in which no function call

syntax appears.—end example ] The sequencing constraints(约束) on the execution of the called function (as described above)

are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.

总结:尽量不要写容易发生误会的表达式,因为运算顺序本身就没有严格规定,所以不要迷信编译器,不要迷信执行结果,有些事情确实是无法定论的。所以之前总结的运算规律,

也只适合考试的时候看看,要真正掌握原理,还是需要用VC时按Alt+8、Alt+6和Alt+5,开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和

寄存器变化(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化)。

而且有时候老师说的东西也是不准确的,面对什么问题,都需要有一种刨根问底的精神。

参考:http://blog.csdn.net/chenbang110/article/details/9192595

参考:http://bbs.csdn.net/topics/370153775

C学习笔记(自增)的更多相关文章

  1. Entity Framework 6 学习笔记2 — 增、删、改、显示简单代码示例

    前言 通过 “Entity Framework 6 学习笔记1 — 介绍和安装方法”文章我相信大家对EF的安装应该没什么问题了,整体安装还是比较简单的,只需要通过Nuge搜索EF然后安装就可以了,这也 ...

  2. 【.NET-EF】Entity Framework学习笔记2 - 增删改(没查询)

    学习描述:用EF就像是省略了做实体类和DAL类,感觉是很方便,废话不多说,直接写步骤: 1.创建EF的edmx文件 这个其实在笔记1已说过,不过有些细节也要说,所以再说一遍,这里使用的是EF 6.1版 ...

  3. 3、MyBatis.Net学习笔记之增删改

    增删改之前先说一下笔记1里提到的一个无法创建ISqlMapper对象的问题. <resultMaps> <resultMap id="FullResultMap" ...

  4. easyui学习笔记1—增删改操作

    最近公司要用easyui,这里自己看了官网几篇文章,遇到些问题,大多数的问题都是敲代码的时候笔误,其他有些地方确实需要注意一下,这里做些笔记. 1.在mysql中建好表之后修改id字段为递增字段,发现 ...

  5. 【转载】ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查.目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的.下面我们通过创建一个简单的Web API来管理联系 ...

  6. SQL Server 2012 学习笔记3 增查改删

    现在举例几个"增查改删"的语句 select * from UserInfor --查找所有字段 select username,UserId from UserInfor -- ...

  7. EF学习笔记——通用增删改查方案

    http://blog.csdn.net/leftfist/article/details/25005307 我刚接触EF未久,还不知道它有什么强大之处,但看上去,EF提供了一般的增删改查功能.以往用 ...

  8. ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查. 目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的. 下面我们通过创建一个简单的Web API来管理 ...

  9. Mybatis学习笔记3 - 增删改查示例

    1.接口定义 package com.mybatis.dao; import com.mybatis.bean.Employee; public interface EmployeeMapper { ...

  10. MongoDB学习笔记,基础+增删改查+索引+聚合...

    一 基础了解 对应关系 -> https://docs.mongodb.com/manual/reference/sql-comparison/ database -> database ...

随机推荐

  1. iOS----------时间戳与NSDate

    1:时间戳转NSDate NSString *timeStamp =@"1545965436"; NSDate *date = [NSDate dateWithTimeInterv ...

  2. gulp+tp5配置

    优化了文件过滤,更改文件只会重新生成修改的文件 项目目录构建: 在入口文件public下,创建html目录,作为前台静态资源目录 gulp.js文件 /*! * gulp * $ npm instal ...

  3. 怎么隐藏 iOS Safari 打开网页时的地址栏和工具栏探索

    先来看一张截图 红色框处就是用手机浏览器打开页面时,自动显示出来的头部地址栏和底部工具栏 如果现在有一个需求,用手机浏览器打开页面时,把地址栏和工具栏隐藏,该怎么办呢? 起初我在度娘找到了好几篇博客都 ...

  4. Java数据结构和算法 - 堆

    堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...

  5. kubernetes中的Pause容器如何理解?

    前几篇文章都是讲的Kubernetes集群和相关组件的部署,但是部署只是入门的第一步,得理解其中的一些知识才行.今天给大家分享下Kubernets的pause容器的作用. Pause容器 全称infr ...

  6. 『练手』004 Laura.SqlForever如何扩展 导航栏 工具栏 右键菜单 插件

    004 Laura.SqlForever如何扩展 导航栏 工具栏 右键菜单 插件 导航栏 插件扩展 比如下图的    窗口 > 关闭所有文档    这个导航栏: 在 任何程序集,任何命名空间,任 ...

  7. springcloud~Eureka实例搭建

    服务端 build.gradle配置 dependencies { compile('org.springframework.cloud:spring-cloud-starter-netflix-eu ...

  8. 外行人都能看懂的SpringCloud,错过了血亏!

    一.前言 只有光头才能变强 认识我的朋友可能都知道我这阵子去实习啦,去的公司说是用SpringCloud(但我觉得使用的力度并不大啊~~)... 所以,这篇主要来讲讲SpringCloud的一些基础的 ...

  9. IO 和 NIO 的思考

    输入输出是操作系统不可或缺的一部分,大致分为两类:面向磁盘和面向网络.在 Java 中有3种 I/O 类型:BIO.NIO 和 AIO,分别是同步阻塞.同步非阻塞和异步非阻塞 I/O,这里着重描述 B ...

  10. XPath和CssSelector定位总结

    1. 介绍XPath和CssSelector 2. XPath有哪些方式 2.1 通过XPath语法 2.2 Contains关键字 2.3 Start-With 2.4 Or和And关键字 2.5 ...