C++运算符的优先级与结合性
C语言运算符的优先级以及结合方向

C语⾔运算符的优先级以及结合⽅向1:运算符的结合⽅向在表达式中,优先级较⾼的先于优先级较低的进⾏运算。
⽽在⼀个运算量两侧的相同时,则按运算符的结合性所规定的结合⽅向处理。
C语⾔中各运算符的结合性分为两种,即左结合性(⾃左⾄右)和右结合性(⾃右⾄左)。
例如的结合性是⾃左⾄右,即先左后右。
如有表达式x-y+z则y应先与“-”号结合,执⾏x-y运算,然后再执⾏+z的运算。
这种⾃左⾄右的结合⽅向就称为“左结合性”。
⽽⾃右⾄左的结合⽅向称为“右结合性”。
最典型的右结合性运算符是。
如x=y=z,由于“=”的右结合性,应先执⾏y=z再执⾏x=(y=z)运算。
2:优先级说明:同⼀优先级的运算符,运算次序由结合⽅向所决定。
简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符(好像不对)关系运算符>逻辑运算符算术运算符>关系运算符优先级运算符名称或含义使⽤形式结合⽅向说明1[]数组下标数组名[常量表达式]左到右()圆括号(表达式)/函数名(形参表).成员选择(对象)对象.成员名->成员选择(指针)对象指针->成员名++后置⾃增运算符++变量名单⽬运算符--后置⾃减运算符--变量名单⽬运算符2-负号运算符-表达式右到左单⽬运算符(类型)强制类型转换(数据类型)表达式++前置⾃增运算符变量名++单⽬运算符--前置⾃减运算符变量名--单⽬运算符*取值运算符*指针变量单⽬运算符&取地址运算符&变量名单⽬运算符!逻辑⾮运算符!表达式单⽬运算符~按位取反运算符~表达式单⽬运算符sizeof长度运算符sizeof(表达式)3/除表达式/表达式左到右双⽬运算符*乘表达式*表达式双⽬运算符%余数(取模)整型表达式/整型表达式双⽬运算符4+加表达式+表达式左到右双⽬运算符-减表达式-表达式双⽬运算符5<<左移变量<<表达式左到右双⽬运算符>>右移变量>>表达式双⽬运算符6>⼤于表达式>表达式左到右双⽬运算符>=⼤于等于表达式>=表达式双⽬运算符<⼩于表达式<表达式双⽬运算符<=⼩于等于表达式<=表达式双⽬运算符7==等于表达式==表达式左到右双⽬运算符!=不等于表达式!= 表达式双⽬运算符8&按位与表达式&表达式左到右双⽬运算符9^按位异或表达式^表达式左到右双⽬运算符10|按位或表达式|表达式左到右双⽬运算符11&&逻辑与表达式&&表达式左到右双⽬运算符12||逻辑或表达式||表达式左到右双⽬运算符13?:条件运算符表达式1? 表达式2:表达式3右到左三⽬运算符=赋值运算符变量=表达式/=除后赋值变量/=表达式14/=除后赋值变量/=表达式右到左<<=左移后赋值变量<<=表达式>>=右移后赋值变量>>=表达式&=按位与后赋值变量&=表达式^=按位异或后赋值变量^=表达式|=按位或后赋值变量|=表达式15,逗号运算符表达式,表达式,…左到右从左向右顺序运算。
c语言中运算符的优先级及结合顺序

C语言中运算符的优先级及结合顺序一、概述C语言是一种广泛应用的计算机编程语言,学习C语言的运算符的优先级及结合顺序对于理解程序的执行过程和写出高效的代码至关重要。
本文将针对C语言中常见的运算符的优先级和结合顺序进行详细的介绍和解析,希望能对读者有所帮助。
二、运算符的优先级1. 括号优先级括号具有最高的优先级,括号中的表达式会先于其他运算符进行计算,其优先级最高。
例如:```int a = 3, b = 4, c = 5;int result = (a + b) * c;```先计算括号中的值,再进行乘法运算。
2. 单目运算符优先级单目运算符的优先级次之,包括正负号、递增递减等运算符。
例如: ```int a = 5;int result = -a;先执行取反操作。
3. 算术运算符的优先级在算术运算符中,乘除法的优先级高于加减法,同级运算符从左到右结合。
例如:```int result = 3 + 4 * 5 / 2;```首先计算乘除法,再进行加减法。
4. 关系运算符的优先级关系运算符(>、<、==等)的优先级次于算术运算符,且具有相同的优先级。
例如:```int a = 3, b = 4, c = 5;int result = a + b > c;```先计算加法,再进行比较运算。
5. 逻辑运算符的优先级逻辑与()、逻辑或(||)等逻辑运算符的优先级相对较低,且具有相同的优先级。
例如:int a = 4, b = 5, c = 6;int result = a > 3 b < 6 || c == 6;```逻辑与的优先级高于逻辑或,但都低于其他运算符。
6. 赋值运算符的优先级赋值运算符的优先级最低,且右结合。
例如:```int a = 5;a += 3;```将3加到a上再赋值给a。
三、运算符的结合顺序1. 左结合性大多数运算符都是左结合的,即从左向右进行计算。
例如: ```int result = 3 + 4 + 5;```从左向右进行加法运算。
《C语言程序设计教程》第三版课后习题参考答案

《C语言程序设计教程》第三版课后习题参考答案C语言程序设计教程第三版课后习题参考答案第一章:C语言概述1.1 C语言的特点答案:C语言是一种通用的、面向过程的程序设计语言,具有高效、简洁、灵活等特点。
它提供了丰富的程序设计元素和功能,适用于各种不同的应用领域。
1.2 C语言程序的基本结构答案:C语言程序由预处理指令、函数声明、函数定义、变量声明和语句组成。
其中,预处理指令用来引入头文件或定义宏,函数声明用来声明函数的名称和参数,函数定义用来实现函数的功能,变量声明用来声明变量的类型和名称,语句用来表达具体的计算过程。
1.3 C语言的数据类型答案:C语言提供了多种数据类型,包括基本类型(整型、浮点型、字符型等)和派生类型(数组、指针、结构体等)。
每种数据类型在内存中占据一定的存储空间,并具有特定的取值范围和操作规则。
1.4 C语言的运算符和表达式答案:C语言支持各种运算符和表达式,例如算术运算符(+、-、*、/等)、关系运算符(>、<、==等)、逻辑运算符(&&、||、!等)等。
通过运算符和表达式可以进行各种数值计算和逻辑判断。
第二章:基本数据类型与运算2.1 整型数据类型答案:C语言提供了不同长度的整型数据类型,包括有符号整型(int、long等)和无符号整型(unsigned int、unsigned long等)。
整型数据类型可以表示整数值,并具有不同的取值范围。
2.2 浮点型数据类型答案:C语言提供了浮点型数据类型(float、double等),用来表示带小数部分的实数值。
浮点型数据可以表示较大或较小的数值,并具有一定的精度。
2.3 字符型数据类型答案:C语言提供了字符型数据类型(char),用来表示单个字符。
字符型数据可以用于表示各种字符(包括字母、数字、符号等)。
2.4 布尔型数据类型答案:C语言不直接支持布尔型数据类型,但可以使用整型数据类型来表示布尔值(0表示假、非零表示真)。
c++运算符的优先级顺序算术运算

C++运算符的优先级顺序在进行算术运算时起着至关重要的作用。
在C++编程中,了解并掌握这些优先级顺序是非常重要的,因为它可以影响到程序的运行结果。
在本文中,我将深入探讨C++运算符的优先级顺序,并结合具体示例来帮助你更好地理解。
让我们来看一下C++中常见的算术运算符,包括加法、减法、乘法、除法和取模运算符。
对于这些运算符,它们的优先级顺序是怎样的呢?在C++中,乘法和除法的优先级高于加法和减法,取模的优先级也高于加法和减法。
这意味着当表达式中同时包含这些运算符时,编译器会按照一定的规则来确定它们的计算顺序。
举个例子,假设我们有一个表达式:a + b * c。
按照C++的规则,乘法运算符的优先级高于加法运算符,所以编译器会首先计算 b * c 的结果,然后再和 a 相加。
如果我们想要改变这个计算顺序,可以使用括号来明确指定计算顺序,比如:(a + b) * c。
除了乘法和加法之外,C++中还存在一元运算符和赋值运算符。
一元运算符包括正号、负号等,它们的优先级高于二元运算符。
赋值运算符的优先级是最低的,因此在表达式中,赋值运算符的计算往往是在最后进行的。
了解了C++运算符的优先级顺序,我们可以更好地编写代码,并且避免一些可能会出现的逻辑错误。
当我们编写复杂的表达式时,需要特别注意运算符的优先级,以确保程序的运行逻辑符合我们的设计意图。
总结来说,掌握C++运算符的优先级顺序对于编写高质量的代码是非常重要的。
我们需要清楚地了解每个运算符的优先级,并合理使用括号来明确指定计算顺序。
只有这样,我们才能编写出更严谨、更清晰的代码,从而提高程序的可读性和可维护性。
通过本文的讨论,希望你能更深入地理解C++运算符的优先级顺序,在日后的编程实践中能够更加熟练地运用这些知识。
我认为掌握这些基础知识是非常重要的,因为它可以帮助我们更好地理解和掌握编程语言的精髓,也能够为我们带来更有意义的编程体验。
希望本文对你有所帮助,也欢迎你共享你的看法和理解。
加减乘除括号运算顺序c语言算法

加减乘除括号运算顺序c语言算法
加减乘除括号运算顺序是数学中的基本概念,也是计算机编程中的重要算法。
在C语言中,我们可以使用各种运算符来进行加减乘除运算,同时也可以使用括号来改变运算的优先级。
在C语言中,加法运算符“+”和减法运算符“-”的优先级相同,都比乘法运算符“*”和除法运算符“/”的优先级低。
因此,在没有括号的情况下,加减运算会先于乘除运算进行。
例如,表达式“3+4*5-6”会先计算4*5,再加上3,最后减去6,得到的结果为17。
如果我们想改变运算的优先级,可以使用括号来明确运算的顺序。
括号中的表达式会先于其他运算进行。
例如,表达式“(3+4)*5-6”会先计算括号中的3+4,得到7,再乘以5,最后减去6,得到的结果为29。
除了加减乘除运算,C语言还支持取模运算符“%”,用于求两个数相除的余数。
取模运算符的优先级与乘除运算符相同,都比加减运算符的优先级高。
例如,表达式“10%3*2”会先计算10%3,得到1,再乘以2,最后得到2。
在编写程序时,我们需要注意运算符的优先级和结合性,以确保程序的正确性。
如果不确定运算的优先级,可以使用括号来明确运算的顺序。
同时,我们还需要注意整数除法的特殊性质,即两个整数相除时,结果会向下取整。
例如,表达式“5/2”会得到2,而不是
2.5。
加减乘除括号运算顺序是C语言中的基本算法,掌握好这些运算符的优先级和结合性,可以帮助我们编写出更加高效和正确的程序。
C基础理论题目及考点(课堂讲解)1_7章

第一章部分 C 程序设计的初步知识一、C 语言的构成(1)源程序由函数构成,每个函数完成相对独立的功能。
(2)每个源程序中必须有且只能有一个主函数,可以放在任何位置,但程序总是从主函数开始执行。
(3)函数体:在函数后面用一对花括号括起来的部分。
(4)每个语句以分号结束,但预处理命令、函数头之后不能加分号。
(5)注释:括在“/* ”与“ */”之间,没有空格,允许出现在程序的任何位置。
(6)预处理命令:以“#”开头的语句。
二、C程序的生成过程(1)C程序是先由源文件经编译生成目标文件,然后经过连接生成可执行文件。
(2)源程序的扩展名为.c,目标程序的扩展名为.obj ,可执行程序的扩展名为.exe 。
试题程序#include <stdlib.h> #include <stdio.h>/* ***found*** */ int fun(int n);{/* ***found*** */ int i/* ***found*** */ sum=0;for(i=1;i<=n;i++) {sum=sum+i; }return sum; }一、标识符在C语言中,变量名、函数名、数组名等按照一定规则命名的符号称为标识符。
1. 标识符的命名规则2.标识符的分类C语言的标识符可以分为3类。
(1)关键字:C语言规定的专用的标识符,它们有着固定的含义,不能更改(见课本附录)。
例如int表示变量类型,不能另作它用。
(2)预定义标识符:和“关键字”一样也有特定的含义。
包括: 库函数的名字,如printf 预处理命令,如define这类标识符与关键字的区别是:C 语言语法允许用户更改预定义标识符的作用,但将失去系统规定的含义。
建议用户不要更改。
(3)用户标识符:由用户根据需要定义的标识符。
一般给变量、函数、数组和文件命名。
【例1】以下选项中不合法的标识符是( )。
A) &aB) FORC) printD) 00注意FOR (大小写不同,for 为关键字)二、常量定义:在程序运行中,其值不能被改变的量。
计算机等级考试 二级C语言讲义 第二讲 运算符和表达式

第二讲主要内容运算符表达式一.运算符1.算术运算符和算术表达式C语言的运算符具有不同的优先级,而且还有一个特点,就是它的结合性。
在表达式中,各运算量参与运算的先后顺序不仅要遵守运算符优先级别的规定,还要受运算符结合性的制约,以便确定是自左向右进行运算还是自右向左进行运算。
这种结合性是其它高级语言的运算符所没有的,因此也增加了C语言的复杂性。
C运算符简介C语言的运算符可分为以下几类:1.算术运算符:用于各类数值运算。
包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增(++)、自减(--)共七种。
2.关系运算符:用于比较运算。
包括大于(>)、小于(<)、等于(==)、大于等于(>=)、小于等于(<=)和不等于(!=)六种。
3.逻辑运算符:用于逻辑运算。
包括与(&&)、或(||)、非(!)三种。
4.赋值运算符:用于赋值运算,分为简单赋值(=)、复合算术赋值(+=,-=,*=,/=,%=)和复合位运算赋值(&=,|=,^=,>>=,<<=)三类共十一种。
5.逗号运算符:用于把若干表达式组合成一个表达式(,)。
6.指针运算符:用于取内容(*)和取地址(&)二种运算。
7.求字节数运算符:用于计算数据类型所占的字节数(sizeof)。
8.特殊运算符:有括号(),下标[],成员(→,.)等几种。
9.条件运算符:这是一个三目运算符,用于条件求值(?:)。
10.位操作运算符:参与运算的量,按二进制位进行运算。
包括位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)六种。
1.1算术运算符和算术表达式1.基本的算术运算符●加法运算符“+”:加法运算符为双目运算符,即应有两个量参与加法运算。
如a+b,4+8等。
具有左结合性。
●减法运算符“-”:减法运算符为双目运算符。
运算符优先级由高到低的顺序

运算符优先级由高到低的顺序
运算符优先级顺序是:! >算术运算符>关系运算符>&&>||>赋值运算符。
1.运算符优先级顺序:同一优先级的运算符,运算次序由结合方向所决定的。
简单的记就是:! >算术运算符>关系运算符>&&>||>赋值运算符。
结合性:2、13 、14是从右至左其他都是从左至右。
2.优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。
表达式的结合次序取决于表达式中各种运算符的优先级。
优先级高的运算符先结合,优先级低的运算符后结合,同一行中的运算符的优先级相同。
3.C语言中大多数运算符的结合性都是从左往右,只有三个运算符是从右往左的。
一个是单目运算符,另一个是三目运算符,还有一个就是双目运算符中的赋值运算符。
运算符的“结合性”也不需要死记硬背,在不断使用中就记住了。
— 1 —。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
c/c++运算符的优先级和结合性内容导读:遍历了15个级别之后,让我们再来总结一下。
其中我们可以看出这样两个规律:规律一、按照操作数个数来区分,一元运算符高于二元运算符,二元运算符高于三元运算符; 规律二、按照运算符的作用来区分,级别最高的是那些不是严格意义上的运算符,次之是算术运算...遍历了15个级别之后,让我们再来总结一下。
其中我们可以看出这样两个规律:规律一、按照操作数个数来区分,一元运算符高于二元运算符,二元运算符高于三元运算符;规律二、按照运算符的作用来区分,级别最高的是那些不是严格意义上的运算符,次之是算术运算符,位移运算符,关系运算符,位运算符,逻辑运算符,赋值运算符。
此外还有两特别的地方需要注意:一、同为关系运算符,但==和!=的级别低于其它四个;二、第2组与第13组的操作符是右结合的,其它的都为左结合;通过分类我们大大减少了需要记忆的内容,遇到使用操作符的时候,我们只需想想它们是什么类型的运算符就可以确定它们之间的相对优先级,从而避免一些不必要的错误。
====================================================================== ===================提起运算符的优先级,很多了解c++的过来人都会想:这有什么难的?不就是谁的优先级高就算谁么。
确实如此,运算符的优先级不是一个大问题,但对于一个初学者来说,却经常容易在上面迷糊与犯错。
而对于一个了解c++的人来说,我相信也会偶尔在上面摔倒,不信就继续往下读。
“优先级高的先运算”带来的困惑c++中运算符的优先级有一张表,表里把运算符进行了分类,这张表是不需要死记硬背的,只要有个大致的轮廓就ok了。
例如应该记住最低优先级是逗号运算符,其次是赋值运算符,再其次是三目运算符。
而关系运算符的优先级高于逻辑运算符(不包括逻辑非运算),算术运算符的优先级高于关系运算符,象++和﹣﹣的优先级比前面几个都高,但最高的要属()了。
知道这些后,你的脑海里一定有一条准则了:优先级高的先运算。
那么下面看一个例子:intx=1,y=0;!x&&x+y&&++y;上面的语句中出现了!、&&、+、++这四个运算符,那么问题来了,到底先算谁呢?有一个姓蔡的同学站起来说,++运算符在这里面优先级最高,理所应当最先算++,既先计算++y,再算!x,再算x+y,最后把它们&&起来。
按照蔡同学的思路,第二步的结果是0&&x+y&&1,由于&&是严格运算,有一个为0结果既为0,所以不需要计算x+y了,整个语句的结果是:假。
按照上面蔡同学的说法,执行完后y的值应该是1了,这对不对呢?一位姓高的同学站起来反驳道,我觉得应该先计算!x,如果值为假,则不需要计算下去,最后结果为假。
如果值为真,再计算x+y,同理如果其值为真,再去计算++y,否则最后结果也为假。
蔡同学不服起来说,高同学你觉得++和!谁的优先级高呢?高同学答道,那当然是++高。
蔡同学接着问,那为什么还要先计算!呢?高同学答不出来了。
是呀,为什么要先算!呢?加括号确定优先级的方法高同学说的是正确的,为什么呢?下面我给大家解释一下。
当多个优先级不同的运算符在一起时,为了不混淆,可以先加上括号,这样就分出层次了,相同层次的考虑结合性问题,当确定下来先算那块时,再往这块里面深入。
例如上面的例子,我们可以这样加上括号:从左向右看,由于!比&&优先级高,所以有(!x),又由于&&比+优先级低,所以有(x+y),而++优先级高于&&,所以(++y)。
这样整个式子就变成了:(!x)&&(x+y)&&(++y),最外层的是两个&&运算,由于&&的结合性是从左至右,所以上式可看成:a&&b&&c,先计算a,再计算b,最后算c。
由于x=1,则!x就为假,后面的就不需要再算了,整个语句的值为假。
执行完后,y的值没变,还是0。
所以碰到不清楚先算谁后算谁时,先加个括号看看,就明白了先后次序。
下面做一个加括号的练习:给语句c=a>b?a:b;加括号。
此语句有三个运算符:=、>、?:,应该怎样加括号呢?第一种方案:c=((a>b)?a:b);第二种方案:c=(a>(b?a:b));第三种方案:(c=a)>(b?a:b);应该是那一种呢?按照运算符优先级的高低顺序,>优先级高于=,所以不可能把(c=a)括起来。
而>优先级高于?:运算符。
所以也不可能把(b?a:b)括起来。
因此,第一种答案正确。
下面再看一个类似的例子:inti=8,j=4,k;k=i<j?++i:++j;猛然一看,有些人上来可能就要计算++i和++j了。
这里不妨先加括号看看。
从左至右看,<的优先级高于=而且又高于?:,所以有k=(i<j)?++i:++j,再继续向右看,由于++高于?:,所以k=(i<j)?(++i):(++j),这样相当于k=a?b:c,先算a的值,若为真,则值为b,即算一下++i,若为假,则值为c,即算一下++j。
整个语句执行完后,k的值为5,i的值为8,j的值为5。
==============================每个操作符拥有某一级别的优先级,同时也拥有左结合性或右结合性。
优先级决定一个不含括号的表达式中操作数之间的“紧密”程度。
例如,在表达式ab+c中,乘法运算的优先级高于加法运算符的优先级,所以先执行乘法ab,而不是加法b+c。
但是,许多操作符的优先级都是相同的。
这时,操作符的结合性就开始发挥作用了。
在表达式中如果有几个优先级相同的操作符,结合性就起仲裁的作用,由它决定哪个操作符先执行。
像下面这个表达式:inta,b=1,c=2;a=b=c;我们发现,这个表达式只有赋值符,这样优秀级就无法帮助我们决定哪个操作先执行,是先执行b=c呢?还是先执行a=b。
如果按前者,a=结果为2,如果按后者,a的结果为1。
所以的赋值符(包括复合赋值)都具有右结合性,就是说在表达式中最右边的操作最先执行,然后从右到左依次执行。
这样,c先赋值给b,然后b在赋值给a,最终a的值是2.类似地,具有左结合性的操作符(如位操作符“&”和“”)则是从左至右依次执行。
结合性只用于表达式中出现两个以上相同优先级的操作符的情况,用于消除歧义。
事实上你会注意到所有优先级相同的操作符,他们的结合性也相同。
这是必须如此的,否则结合性依然无法消除歧义,如果在计算表达式的值时需要考虑结合性,那么最好把这个表达式一分为二或者使用括号。
==============================裘宗燕:c/c++语言中的表达式求值经常可以在一些讨论组里看到下面的提问:“谁知道下面c语句给n赋什么值?”m=1;n=m+++m++;最近有位不相识的朋友发email给我,问为什么在某个c++系统里,下面表达式打印出两个4,而不是4和5:a=4;cout<<a++<<a;c++不是规定<<操作左结合吗?是c++书上写错了,还是这个系统的实现有问题?要弄清这些,需要理解的一个问题是:如果程序里某处修改了一个变量(通过赋值、增量/减量操作等),什么时候从该变量能够取到新值?有人可能说,“这算什么问题!我修改了变量,再从这个变量取值,取到的当然是修改后的值!”其实事情并不这么简单。
c/c++语言是“基于表达式的语言”,所有计算(包括赋值)都在表达式里完成。
“x=1;”就是表达式“x=1”后加表示语句结束的分号。
要弄清程序的意义,首先要理解表达式的意义,也就是:1)表达式所确定的计算过程;2)它对环境(可以把环境看作当时可用的所有变量)的影响。
如果一个表达式(或子表达式)只计算出值而不改变环境,我们就说它是引用透明的,这种表达式早算晚算对其他计算没有影响(不改变计算的环境。
当然,它的值可能受到其他计算的影响)。
如果一个表达式不仅算出一个值,还修改了环境,就说这个表达式有副作用(因为它多做了额外的事)。
a++就是有副作用的表达式。
这些说法也适用于其他语言里的类似问题。
现在问题变成:如果c/c++程序里的某个表达式(部分)有副作用,这种副作用何时才能实际体现到使用中?为使问题更清楚,我们假定程序里有代码片段“...a[i]++...a[j]...”,假定当时i与j的值恰好相等(a[i]和a[j]正好引用同一数组元素);假定a[i]++确实在a[j]之前计算;再假定其间没有其他修改a[i]的动作。
在这些假定下,a[i]++对a[i]的修改能反映到a[j]的求值中吗?注意:由于i与j相等的问题无法静态判定,在目标代码里,这两个数组元素访问(对内存的访问)必然通过两段独立代码完成。
现代计算机的计算都在寄存器里做,问题现在变成:在取a[j]值的代码执行之前,a[i]更新的值是否已经被(从寄存器)保存到内存?如果了解语言在这方面的规定,这个问题的答案就清楚了。
程序语言通常都规定了执行中变量修改的最晚实现时刻(称为顺序点、序点或执行点)。
程序执行中存在一系列顺序点(时刻),语言保证一旦执行到达一个顺序点,在此之前发生的所有修改(副作用)都必须实现(必须反应到随后对同一存储位置的访问中),在此之后的所有修改都还没有发生。
在顺序点之间则没有任何保证。
对c/c++语言这类允许表达式有副作用的语言,顺序点的概念特别重要。
现在上面问题的回答已经很清楚了:如果在a[i]++和a[j]之间存在一个顺序点,那么就能保证a[j]将取得修改之后的值;否则就不能保证。
c/c++语言定义(语言的参考手册)明确定义了顺序点的概念。
顺序点位于:1.每个完整表达式结束时。
完整表达式包括变量初始化表达式,表达式语句,return语句的表达式,以及条件、循环和switch语句的控制表达式(for头部有三个控制表达式);2.运算符&&、、?:和逗号运算符的第一个运算对象计算之后;3.函数调用中对所有实际参数和函数名表达式(需要调用的函数也可能通过表达式描述)的求值完成之后(进入函数体之前)。
假设时刻ti和ti+1是前后相继的两个顺序点,到了ti+1,任何c/c++系统(vc、bc等都是c/c++系统)都必须实现ti之后发生的所有副作用。
当然它们也可以不等到时刻ti+1,完全可以选择在时段[t,ti+1]之间的任何时刻实现在此期间出现的副作用,因为c/c++语言允许这些选择。