运算符的优先级和结合性有明确的规定,但是,除少数例外情况外,表达式的求值次序没有定义,甚至某些有副作用的子表达式也没有定义。

也就是说运算符的定义保证了其操作数按某一特定的顺序求值,否则具体实现可以自由选择任意求值顺序,甚至可以交换求值次序。但是每个运算符

将其操作数生成的值结合起来的方式与表达式的语法分析方式是兼容的。(该规则废除了原先的一个规则:当表达式中的运算符在数学上满足交换律

和结合律时,可以对表达式重新排序)

  以下按优先级从高到底:

  1.指针生成;

  2.初等表达式;

  3.后缀表达式;

  4.一元运算符(+ - *  &  !  ~  sizeof);

  5.强制类型转换;

  6.乘法类运算符(*  %  /);

  7.加法类运算符( +  - );

  8.移位运算符(<<   >>);

  9.关系运算符(<  >   <=   >= );

  10.相等类运算符( ==  !=);

  11.按位与运算符(&);

  12.按位异或运算符( ^);

  13.按位或运算符(|);

  14.逻辑与运算符(&&);

  15.逻辑或运算符(||);

  16.条件运算符(a?b:c);

  17.赋值运算符(=  +=  -=  *=  /=  %=   <<=   >>=   &=   |=   ^=);

  18.逗号运算符(,);

      求值顺序由左向右,并且左表达式的值被丢弃

  19.常量表达式;

注:

 运算符&&遵循从左到右的结合性:首先计算第一个操作数,包括所有可能的副作用;如果为0,则整个表达式的值为0;否则,计算右操作数,如果为0,则整个表达式
 的值为0,否则为1

 运算符|| 同&& 先计算第一个值如能判断结果则后面的值不再计算,否则计算第二个操作数

  如   a=1;  b=0;   if(a > b  || (a=2)>0)的值为 1,且此时 a 的值为1,而不是 2

其他简单例子:

  1)a<b==c<d;   只要a<b和c<d具有相同的值,其值总为1

  2)a=1;  b=2;  c=1;  a*b+c?1:0  的值为 1. 条件运算符优先级较低 所以相当于(a*b+c)?1:0  而非1*2+1=3

  3)b=2,c=7,d=5;  a1=(++b,c--,d+3);  a2=++b,c--,d+3;

     对于给a1赋值的代码,有三个表达式,用逗号分开,所以最终的值应该是最后一个表达式的值,也就是(d+3)的值,为8,所以a1的值为8

     对于给a2赋值的代码,也是有三个表达式,这时的三个表达式为a2=++b、c--、d+3,(这是因为赋值运算符比逗号运算符优先级高)

       注:a2行代码不能编译通过,仅作举例说明问题、

     所以最终表达式的值虽然也为8,但a2=4(a1行代码运算完时,b=3,a2行代码运行时,b的值为4)。

作者说:对于运算符的优先级不确定时,请使用括号。不仅不会出错,也有利于代码的易读性。

  

附图:

        运算符的优先级和结合性

注:一元运算符 正号+ 符号- 取址&  指针* 比二元运算符 +  -  *的优先级高。

另注:

  C语言中没有指定有意运算符中多个操作数的计算顺序,如  a = f() + g(); 中,f()可以在g()之前计算,也可以在g()

之后计算。因此,如果函数f或g改变了另一函数的使用的变量,那么a的结果可能会依赖于两个函数的计算顺序。

  ANSI C 明确规定所有对参数的副作用都必须在函数调用之前生效。

  类似的,c中也没有指定个参数的求值顺序。因此,形如

  printf("%d %d\n",++n,power(2,n));  的语句是错误的。在不同的编译器中可能产生不同的结果。应改为:

  ++n; printf("%d %d\n",n,power(2,n));

同样形如  a[i] = i++;数组下标是引用旧值还是引用新值?在不同的编译器中可能产生不同的结果。、

所以形如  i=1; (i++)+(i++)+(i++)+(i++)这样的代码是千万要不得的。(顺便说一下,在clion中运行结果是10.。。不推荐浪费时间在这类问题上!)

重读The C programming Lanuage 笔记二:运算符优先级的更多相关文章

  1. 重读The C programming Lanuage 笔记四:c预处理

    C预处理器执行宏替换.条件编译以及包含指定的文件.以#开头的命令行就是与处理器的对象.这些命令行的语法独立于语言的其他部分,它们可以出现在任何地方,其作用可延续到所在编译单元的末尾(与作用域无关).行 ...

  2. 重读The C programming Lanuage 笔记一:类型转换

    首先说自动类型转换: 当一个运算符的几个操作数类型不同时,就需要吧他们转换位某种共同的类型.一般来说,自动转换把“较低”的类型转换为”较高“的类型.运算结果为较高的类型 以下是不严格的规则: 首先,如 ...

  3. 重读The C programming Lanuage 笔记三:简单计算器程序

    //简单计算器 #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <str ...

  4. swift笔记(二) —— 运算符

    基本运算符 Swift支持大部分的标准C语言的操作符,而且做了一些改进,以帮助开发人员少犯低级错误,比方: 本该使用==的时候,少写了个=, if x == y {-} 写成了 if x = y {- ...

  5. Linux System Programming 学习笔记(二) 文件I/O

    1.每个Linux进程都有一个最大打开文件数,默认情况下,最大值是1024 文件描述符不仅可以引用普通文件,也可以引用套接字socket,目录,管道(everything is a file) 默认情 ...

  6. Golang的运算符优先级实操案例

    Golang的运算符优先级实操案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.运算符优先级案例 运算符是用来在程序运行时执行数学或逻辑运算的,在Go语言中,一个表达式可以包 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(二) indigo tools

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  8. STM32学习及应用笔记二:一次运算符优先级造成的错误

    本人在最近一个项目的开发中,出现一个应为疏忽运算符优先级造成的问题,检查了很久才发现问题,所以觉得运算符的优先级问题还是有必要再研究一下.具体的问题是这样的,我采集了传感器的原始数据,然后会对数据进行 ...

  9. iOS阶段学习第三天笔记(运算符)

    iOS学习(C语言)知识点整理笔记 1.运算符 一.算术运算符 1)表达式由变量.常量.运算符构成,有确定的类型和值 2)算术运算符包括: +(加),-(减),*(乘),/(除),%(模) 3)算术运 ...

随机推荐

  1. jvm内存JVM学习笔记-引用(Reference)机制

    在写这篇文章之前,xxx已经写过了几篇关于改jvm内存主题的文章,想要了解的朋友可以去翻一下之前的文章 如果你还不了解JVM的基本概念和内存划分,请阅读JVM学习笔记-基础知识和JVM学习笔记-内存处 ...

  2. jquery ajax请求成功,数据返回成功,seccess不执行的问题

    1.状态码返回200--表明服务器正常响应了客户端的请求:       2.通过firebug和IE的httpWatcher可以看出服务器端返回了正常的数据,并且是符合业务逻辑的数据.         ...

  3. .NET基础——循环、枚举

    1. 循环结构 3种循环语句:while.do-while.for 面对循环我们应当注意: 1. 循环在做什么?(重复做的事情——也就是循环体的内容) 2. 循环的终止条件是什么?(循环条件) 3种循 ...

  4. Linux学习笔记(一):常用命令(2)

    3.帮助命令 A,帮助命令:man    B,其他帮助命令 3.1,格式:man [命令名] 查看命令拥有哪个级别的帮助:                                       ...

  5. C#开发学习——存储过程

    举个例子: 带输入参数的存储过程计算班级中英语和数学不及格的人数      if(exists(select * from sys.objects where name='usp_GetFailCou ...

  6. python 函数简介之三

    1. 非固定个数的实参----参数组,* args ,其结果将以元组的形式呈现出来 def func(*args): print(args) func(1,2,3,4,5) #第一种调用方式, 多个实 ...

  7. JavaScript构造函数+原型创建对象,原型链+借用构造函数模式继承父类练习

    虽然经常说是做前端开发的,但常常使用的技术反而是JQuery比较多一点.在JavaScript的使用上相对而言少些.尤其是在创建对象使用原型链继承上面,在项目开发中很少用到.所以今天做个demo练习一 ...

  8. 【NOIP2014】Day1题解+代码

    Day1 T1 签到题,模拟一下随便写就能过. 不过小心像我一样表打错傻逼的调了10min. #include <algorithm> #include <iostream> ...

  9. Salesforce自主学习(一)

    Salesforce学习--接触Apex: 学习目标: 1.描述出Apex程序语言的关键特点: 2.保存一个Apex类并用另一个Apex类来调用它的方法: 3.使用Developer Console检 ...

  10. CODE[VS]-最小数和最大数-整数处理-天梯青铜

    题目描述 Description 输入n个数,n<=100,找到其中最小的数和最大的数 输入描述 Input Description 第一行一个整数n 接下来一行n个整数,每个整数不超过231 ...