本人在最近一个项目的开发中,出现一个应为疏忽运算符优先级造成的问题,检查了很久才发现问题,所以觉得运算符的优先级问题还是有必要再研究一下。具体的问题是这样的,我采集了传感器的原始数据,然后会对数据进行一些处理,在其中的一种条件下会对一个数进行左移几位并加上一个数。类似的操作在其他地方也有,但只在这个地方忘记了一个括号,所以得出了结果总是存在偏差,只好从头开始查找,花了不少时间才发现这出错误。

其实本人平时还是非常注意代码规范的,但也有一时疏忽的,确实运算符的优先级有时候让人迷惑。下面我们简单的总结一下C语言中运算符的优先级问题。C语言中各运算符的优先级如下表所示:

优先级

运算符

名称或含义

使用形式

结合方向

说明

1

[]

数组下标

数组名[常量表达式]

左到右

 

()

圆括号

(表达式)/函数名(形参表)

 

.

成员选择(对象)

对象.成员名

 

->

成员选择(指针)

对象指针->成员名

 

++

后置自增运算符

++变量名

单目运算符

--

后置自减运算符

--变量名

单目运算符

2

-

负号运算符

-表达式

右到左

单目运算符

(类型)

强制类型转换

(数据类型)表达式

 

++

前置自增运算符

变量名++

单目运算符

--

前置自减运算符

变量名--

单目运算符

*

取值运算符

*指针变量

单目运算符

&

取地址运算符

&变量名

单目运算符

!

逻辑非运算符

!表达式

单目运算符

~

按位取反运算符

~表达式

单目运算符

sizeof

长度运算符

sizeof(表达式)

 

3

/

表达式/表达式

左到右

双目运算符

*

表达式*表达式

双目运算符

%

余数(取模)

整型表达式/整型表达式

双目运算符

4

+

表达式+表达式

左到右

双目运算符

-

表达式-表达式

双目运算符

5

<<

左移

变量<<表达式

左到右

双目运算符

>>

右移

变量>>表达式

双目运算符

6

>

大于

表达式>表达式

左到右

双目运算符

>=

大于等于

表达式>=表达式

双目运算符

<

小于

表达式<表达式

双目运算符

<=

小于等于

表达式<=表达式

双目运算符

7

==

等于

表达式==表达式

左到右

双目运算符

!=

不等于

表达式!= 表达式

双目运算符

8

&

按位与

表达式&表达式

左到右

双目运算符

9

^

按位异或

表达式^表达式

左到右

双目运算符

10

|

按位或

表达式|表达式

左到右

双目运算符

11

&&

逻辑与

表达式&&表达式

左到右

双目运算符

12

||

逻辑或

表达式||表达式

左到右

双目运算符

13

?:

条件运算符

表达式1? 表达式2: 表达式3

右到左

三目运算符

14

=

赋值运算符

变量=表达式

右到左

 

/=

除后赋值

变量/=表达式

 

*=

乘后赋值

变量*=表达式

 

%=

取模后赋值

变量%=表达式

 

+=

加后赋值

变量+=表达式

 

-=

减后赋值

变量-=表达式

 

<<=

左移后赋值

变量<<=表达式

 

>>=

右移后赋值

变量>>=表达式

 

&=

按位与后赋值

变量&=表达式

 

^=

按位异或后赋值

变量^=表达式

 

|=

按位或后赋值

变量|=表达式

 

15

,

逗号运算符

表达式,表达式,…

左到右

从左向右顺序运算

在上表中,同一优先级的运算符,运算次序由结合方向所决定。当然大部分的运算符都是左结合的,与我们的常识一致,但要记住有一部分运算符是右结合的,实在记不住也没有关系,我们可以在编写代码时以( )加以规范。

当然,事情并非我们希望的那么简单。在上表中,如果优先级同为1 的几种运算符同时出现时,想要确定表达式的优先级就会让大家,特别是初学者感到迷惑不解。接下来我们整理了一些容易出错的情况:

优先级问题

表达式

想要的结果

实际结果

.的优先级高于*

*p.f

指针p所指向的对象的某一字段f,即:(*p).f

对p取f偏移作为指针,然后进行解除饮用操作,即:*(p.f)

[]的优先级高于*

int *p[]

P是指向int数组的指针,即:int (*p)[]

P是元素为指向int的指针的数组,即:int *(p[])

函数()优先级高于*

int *p()

p是个函数指针所指函数返回值是int,即:int (*p)()

P是个函数,返回值是int   *,即:int *(p())

==和!=优先级高于位操作

(val&mask!=0)

(val&mask)!=0

val&(mask!=0)

==和!=优先级高于赋值操作

c=getchar()!=EOF

(c=getchar())!=EOF

c=(getchar()!=EOF)

算术运算符高于移位运算符

msb<<4+lsb

(msb<<4)+lsb

msb<<(4+lsb)

逗号运算符的优先级最低

i=1,2

i=(1,2)

(i=1),2

当然,熟记上面这个表中的东西可以减少犯错,但归根到底,最关键是多写代码多使用,熟练了自然就没问题了。

STM32学习及应用笔记二:一次运算符优先级造成的错误的更多相关文章

  1. C语言学习及应用笔记之一:C运算符优先级及使用问题

    C语言中的运算符绝对是C语言学习和使用的一个难点,因为在2011版的标准中,C语言的运算符的数量超过40个,甚至比关键字的数量还要多.这些运算符有单目运算符.双目运算符以及三目运算符,又涉及到左结合和 ...

  2. STM32学习及应用笔记一:SysTick定时器学习及应用

    这几年一直使用STM32的MCU,对ARM内核的SysTick计时器也经常使用,但几乎没有仔细了解过.最近正好要在移植一个新的操作系统时接触到了这块,据比较深入的了解了一下. 1.SysTick究竟是 ...

  3. Vue学习计划基础笔记(二) - 模板语法,计算属性,侦听器

    模板语法.计算属性和侦听器 目标: 1.熟练使用vue的模板语法 2.理解计算属性与侦听器的用法以及应用场景 1. 模板语法 <div id="app"> <!- ...

  4. swift 笔记 (二十一) —— 高级运算符

    高级运算符 位运算符 按位取反: ~ 按位与运算:  & 按位或运算:  | 按位异或运算:  ^ 按位左移运算: << 按位右移动算: >> 溢出运算符 自从swif ...

  5. STM32学习笔记(二) 基于STM32-GPIO的流水灯实现

    学会了如何新建一个工程模板,下面就要开始动手实践了.像c/c++中经典的入门代码"hello world"一样,流水灯作为最简单的硬件设备在单片机领域也是入门首推.如果你已经有了一 ...

  6. STM32学习笔记(四)——串口控制LED(中断方式)

    目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...

  7. STM32学习笔记——OLED屏

    STM32学习笔记--OLED屏 OLED屏的特点: 1.  模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2.  显示尺寸为0.96寸 3.  分辨率为128*64 4.   ...

  8. STM32学习笔记——点亮LED

    STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1 ...

  9. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

随机推荐

  1. poj 2763(RMQ+BIT\树链剖分)

    传送门:Problem 2763 https://www.cnblogs.com/violet-acmer/p/9686774.html 题意: 一对夫妇居住在xx村庄,小屋之间有双向可达的道路,不会 ...

  2. JS面试题(二)(常见算法编程)

    1.字符串转驼峰 例如:border-bottom-color ----> borderBottomColor var str="border-bottom-color"; ...

  3. hbase记录-修改压缩格式

    在业务空闲的时候修改压缩格式 先测试 ---测试表create 'test', { NAME => 'c',VERSIONS => 1}desc 'test'disable 'test'a ...

  4. Git Bash使用详细教程

    https://blog.csdn.net/wangrenbao123/article/details/55511461/

  5. Javaweb学习笔记——(三)——————JavaScript基础&DOM基础

    day031.js的String对象 **创建String对象 ***var str = "abc"; **方法和属性(文档) ***属性 lenth:字符串的长度 ***方法 ( ...

  6. 设置通过Maven创建的工程的JDK版本—一劳永逸

    设置通过Maven创建的工程的JDK版本—一劳永逸 [1]打开settings.xml文件 [2]找到profiles标签 [3]加入一下配置   <profile> <id> ...

  7. MySQL - 日常操作一 增删改查

    mysql 源码安装 创建 mysql  账户 组 groupadd mysql useradd mysql -g mysql -M -s /bin/false 解压缩源码安装 .tar.gz cd ...

  8. 日历控件QCalendarWidget

    样式:

  9. cdn.dns,cms

    CDN CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各 ...

  10. class特性

    每个HTML元素都可以附带一个class特性.有时候,你希望有一种方法可以指定多个元素并将这些元素和页面上的其他元素区分出来,而不是单独指定文档中的某个元素. <!DOCTYPE html> ...