发 帖  
原厂入驻New
[经验]

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

2017-6-3 12:18:22  1634 C语言
分享
0
    本人在最近一个项目的开发中,出现一个应为疏忽运算符优先级造成的问题,检查了很久才发现问题,所以觉得运算符的优先级问题还是有必要再研究一下。具体的问题是这样的,我采集了传感器的原始数据,然后会对数据进行一些处理,在其中的一种条件下会对一个数进行左移几位并加上一个数。类似的操作在其他地方也有,但只在这个地方忘记了一个括号,所以得出了结果总是存在偏差,只好从头开始查找,花了不少时间才发现这出错误。
    其实本人平时还是非常注意代码规范的,但也有一时疏忽的,确实运算符的优先级有时候让人迷惑。下面我们简单的总结一下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
pf偏移作为指针,然后进行解除饮用操作,即:*(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
当然,熟记上面这个表中的东西可以减少犯错,但归根到底,最关键是多写代码多使用,熟练了自然就没问题了。

相关经验

曹操 2017-6-3 13:29:51
有時候不知道优先级,加个括号就行了
回复

举报

尹星 2017-6-3 14:08:28
顶一下了哦,不错
回复

举报

尹星 2017-6-3 14:08:39
楼主很用心了,哦,
回复

举报

李小春 2017-6-4 10:05:34
很好,谢谢!
回复

举报

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发经验
快速回复 返回顶部 返回列表