优先级、结合性这些概念在初学的时候并没有放在心上,今天又碰到这个问题,查了不少资料,再次做个总结。

在标准C语言的文档里,对操作符的结合性并没有做出非常清楚的解释。一个满分的回答是:它是仲裁者,在几个操作符具有相同的优先级时决定先执行哪一个。

每个操作符拥有某一级别的优先级,同时也拥有左结合性或右结合性。优先级决定一个不含括号的表达式中操作数之间的“紧密”程度。例如,在表达式a*b+c中,乘法运算的优先级高于加法运算符的优先级,所以先执行乘法a*b,而不是加法b+c。

但是,许多操作符的优先级都是相同的。这时,操作符的结合性就开始发挥作用了。在表达式中如果有几个优先级相同的操作符,结合性就起仲裁的作用,由它决定哪个操作符先执行。像下面这个表达式:

int a,b=1,c=2;

a=b=c;

我们发现,这个表达式只有赋值符,这样优先级就无法帮助我们决定哪个操作先执行,是先执行b=c呢?还是先执行a=b。如果按前者,a=结果为2,如果按后者,a的结果为1。

所有的赋值符(包括复合赋值)都具有右结合性,就是在表达式中最右边的操作最先执行,然后从右到左依次执行。这样,c先赋值给b,然后b在赋值给a,最终a的值是2。类似地,具有左结合性的操作符(如位操作符“&”和“|”)则是从左至右依次执行。

结合性只用于表达式中出现两个以上相同优先级的操作符的情况,用于消除歧义。事实上你会注意到所有优先级相同的操作符,它们的结合性也相同。这是必须如此的,否则结合性依然无法消除歧义,如果在计算表达式的值时需要考虑结合性,那么最好把这个表达式一分为二或者使用括号。

例:

a=b+c+d

=是右结合的,所以先计算(b+c+d),然后再赋值给a

+是左结合的,所以先计算(b+c),然后再计算(b+c)+d

C语言中具有右结合性的运算符包括所有单目运算符以及赋值运算符(=)和条件运算符。其它都是左结合性。

在C语言中有少数运算符在C语言标准中是有规定表达式求值的顺序的:

1:&& 和 || 规定从左到右求值,并且在能确定整个表达式的值的时候就会停止,也就是常说的短路。

2:条件表达式的求值顺序是这样规定的:

test ? exp1:exp2;

条件测试部分test非零,表达式exp1被求值,否则表达式exp2被求值,并且保证exp1和exp2两者之中只有一个被求值。

3:逗号运算符的求值顺序是从左到右顺序求值,并且整个表达式的值等于最后一个表达式的值,注意逗号','还可以作为函数参数的分隔符,变量定义的分隔符等,这时候表达式的求值顺序是没有规定的!

判断表达式计算顺序时,先按优先级高的先计算,优先级低的后计算,当优先级相同时再按结合性,或从左至右顺序计算,或从右至左顺序计算。

说完了优先级和结合性,下面说说自增运算符++

首先明白自增运算符的两种使用情况:

(1)、单独使用:i++;或者++1;这种情况下两者是没有区别的,i的值都会增加1;

(2)、在表达式中使用:a = i++;此时先取i的值赋给a,然后i的值自增,相当于a = i;i=i+1

a = ++i;此时先让i自增,然后将自增后的值赋给a,相当于i = i + 1;a = i

明白了自增的这两种情况,然后再来看看自增和结合性的混合情况:*p++ (*p)++ *(p++)三者的区别

对于*p++,首先*和++的优先级相同,然后看他们的结合性;由于优先级相同,那么他们的结合性必然也相同,都是右结合(从右至左)。

那么*p++ 就相当于*(p++),即根据右结合,p与++先结合形成(p++),然后再与*结合。

需要注意的一点(本文想着重说明的一点):虽然*(p++)中,p++被放在了括号内,此时应根据自增运算符++的两种情况来考虑(而不需要考虑结合性了,此时与结合性已经无关),显然这是上述的第二种情况,即在表达式中使用自增。所以是先取p的值与*结合,然后p值再自增,相当于*p,p++;千万不要被括号迷惑,认为括号中的东西先运算。

明白了上面一点,则对于*(++p)就很好理解,p先自增,然后与*结合。

对于下面的例子也不难理解:

例一:char q[5] = "am";char *p = q;

那么,

(*p)++后,p就变成了"bm";因为是进行对其首元素进行加1运算

*(p++)后,p就变成了"m",因为完成取值运算后,p++指向下一个元素,即m,

*p++与*(p++)一样。

如果只是征对这3个语句赋值给其他变量的话,3个的结果都是a,在这里。

char o = (*p)++;

char m = *(p++);

char n = *p++;

都是a。

例二:

int i = 0,a,b;

a = (i++)+(i++)+(i++);

b = (++i)+(++i)+(++i);

cout<

输出结果(gcc编译器):0 16 6

解释:这里特别注明是gcc编译器,在其他编译器下的值可能不同。

对于int a=(i++)+(i++)+(i++);先取出i值进行加运算,然后再执行i的三次自增; 在其他编译器下(如tc3.0),可能是0+1+2=3;

对于int b=(++i)+(++i)+(++i);每次i先自增,然后参与运算,所以是4+5+6=16.

c语言之优先级 结合性与自增运算,C语言之优先级、结合性与自增运算相关推荐

  1. c语言中赋值的时候顿号的作用,C语言运算符及其优先级汇总表口诀

    在看一些字符串问题的时候,经常出现这样的语句, *tmp++ = *p;比如tmp和p是指向数组元素的指针,那么这个语句的执行顺序是怎样的呢?正确的理解是*tmp,将*p赋给*tmp后tmp++.但是 ...

  2. C语言两个自增相加,C语言前自增与后自增

    C语言前自增与后自增教程 在 前自减与后自减的区别是前自减是先自减后赋值,后自减是先赋值后自减. C语言前自增与后自增区别 语法 运算符 语法 例子 结果 后自增 a++ int a = 0; int ...

  3. c语言乘法运算 相对于,C语言中,求余运算与乘除法运算,哪个的优先级高

    C语言中,求余运算与乘除法运算,优先级一样高. C语言是一门面向过程的.抽象化的通用程序设计语言,广泛应用于底层开发.C语言能以简易的方式编译.处理低级存储器.C语言是仅产生少量的机器语言以及不需要任 ...

  4. c语言设置程序的优先级,stm32程序中涉及到c语言优先级

    遇到的问题:RxMessage->StdId = (u32)0x000007FF & (CAN->sFIFOMailBox[FIFONumber].RIR >> 21) ...

  5. 关于c语言的基本知识,第二章_关于C语言的基本知识.ppt

    第二章_关于C语言的基本知识.ppt 函数 函数说明 例2.3 分析下面的运行结果. main() { printf("\"123\"\\\"456\" ...

  6. c语言的44种运算符,C语言重要知识点总结【9】:C语言运算符(详解)

    目录 一.前言 二.运算符分类 三.运算符的优先级 四.常用运算符 1. 算术运算符 2. 关系运算符 3. 逻辑运算符 4. 赋值运算符 5. 条件运算符 6. 逗号运算符 7. 强制类型转换运算符 ...

  7. c语言字符怎么运算,c语言运算符号(c语言如何输入运算符号)

    C语言运算符都有那些!各个运算符表示什么,怎么排列麻烦各位老师下,谢. 运算符的种类C语言的运算符可分为以下几类: 1.算术运算符 用于各类数值运算.包括加(+).减(-).乘(*).除(/).求余( ...

  8. java 对数运算_Java语言 第二章 运算和语句

    1.数据运算 运算由表达式表示,表达式由运算符和运算分量组成,运算分量可以是常量.变量和方法调用Java基本运算分类图 1.1 赋值运算 1.1.1 简单赋值运算变量 = 表达式 程序执行过程: (1 ...

  9. c语言由高到低的运算符,求解C语言关系运算符优先极由高到低列表(同级请用括号)...

    满意答案 一般而言,单目运算符优先级较高,赋值运算符优先级低.算术运算符优先级较高,关系和逻辑运算符优先级较低.多数运算符具有左结合性,单目运算符.三目运算符.赋值运算符具有右结合性. 恩,问这个问题 ...

最新文章

  1. 大触教你如何调节python内置函数
  2. html怎么让方块自动旋转,纯CSS3做的的3D旋转方块
  3. adb 多点触碰_无法触及的神话
  4. C++ PAT 乙级 ——1003 我要通过
  5. 2017年3月27日上午学习日志
  6. Java 按字节获得字符串(中文)长度
  7. Centos5上部署udev
  8. 怎样通过Java程序提交yarn的mapreduce计算任务
  9. qt lineedit获取内容_Qt开发中的几个关键知识点,收藏以备参考
  10. 【算法设计】最大子矩阵问题
  11. python中home定义是什么_关于python中的module你需要了解的
  12. 百度地图根据经纬度计算距离php,百度地图两者经纬度距离计算
  13. 6.5-6.7 理解线性方程组解的结构
  14. JAVA中级(五)response(1)基本介绍,代表响应的类,如何设置响应头,行,体
  15. 常用电路设计之PRBS伪随机码发生器的设计
  16. oracle 导入设置字符集,Oracle数据导入时,字符集问题解决
  17. 贪婪算法————背包问题
  18. ios本地化_本地化101 iOS与Android
  19. Java+spring+springmvc 基于ssm的师生防疫登记备案系统设计#毕业设计
  20. [词根词缀]leg/lega/lev/liber/lig词根由来

热门文章

  1. 3类6种,主流容器操作系统全比较
  2. 安全,从写第一行代码开始!
  3. 虚拟化精华问答 | 什么是虚拟化?
  4. Cloud一分钟 |亚马逊市值被微软反超;GKE全球大宕机长达19小时;苹果市值跌破9000亿美元...
  5. 如何成为云计算专家?这些必须知道
  6. Rancher创始人谈Docker,创新愈发困难,未来将何去何从?
  7. java jdbc 连接mysql数据库,Java 通过JDBC连接Mysql数据库
  8. 企业微信H5_身份验证,PC网站企业微信扫码授权登录
  9. uni-app中使用腾讯位置服务实现小程序地图选点功能
  10. ElasticSearch 文档路由,你的数据到底存在哪一个分片上_06