C语言应用笔记(一):运算符优先级和使用问题
C 语言运算符是说明特定操作的符号,它是构造 C 语言表达式的工具。C 语言的运算异常丰富,除了控制语句和输入输出以外的几乎所有的基本操作都为运算符处理。除了常见的三大类,算术运算符、关系运算符与逻辑运算符之外,还有一些用于完成特殊任务的运算符,比如位运算符。
C 语言中的运算符绝对是 C 语言学习和使用的一个难点,因为在2011版的标准中,C 语言的运算符的数量超过40个,甚至比关键字的数量还要多。
1、运算符及优先级
运算符多的好处之一是使用灵活方便,但这涉及到运算符之间的优先级问题。比如做四则运算时,有先乘除后加减的规定,但是 C 语言中的运算符已经远不止四则运算中的加减乘除了,还有其他很多运算符。当它们出现在同一个表达式中时先计算谁后计算谁呢?
C 语言中各运算符的优先级如下表:
优先级 |
运算符 |
名称或含义 |
使用形式 |
结合方向 |
说明 |
1 |
[] |
数组下标 |
数组名[常量表达式] |
左到右 |
|
() |
圆括号 |
(表达式)/函数名(形参表) |
|||
. |
成员选择(对象) |
对象.成员名 |
|||
-> |
成员选择(指针) |
对象指针->成员名 |
|||
++ |
后置自增运算符 |
++变量名 |
单目运算符 |
||
-- |
后置自减运算符 |
--变量名 |
单目运算符 |
||
2 |
- |
负号运算符 |
-表达式 |
右到左 |
单目运算符 |
(类型) |
强制类型转换 |
(数据类型)表达式 |
|||
++ |
前置自增运算符 |
变量名++ |
单目运算符 |
||
-- |
前置自减运算符 |
变量名-- |
单目运算符 |
||
* |
取值运算符 |
*指针变量 |
单目运算符 |
||
& |
取地址运算符 |
&变量名 |
单目运算符 |
||
! |
逻辑非运算符 |
!表达式 |
单目运算符 |
||
~ |
按位取反运算符 |
~表达式 |
单目运算符 |
||
sizeof |
长度运算符 |
sizeof(表达式) |
|||
3 |
/ |
除 |
表达式/表达式 |
左到右 |
双目运算符 |
* |
乘 |
表达式*表达式 |
双目运算符 |
||
% |
余数(取模) |
整型表达式/整型表达式 |
双目运算符 |
||
4 |
+ |
加 |
表达式+表达式 |
左到右 |
双目运算符 |
- |
减 |
表达式-表达式 |
双目运算符 |
||
5 |
<< |
左移 |
变量<<表达式 |
左到右 |
双目运算符 |
>> |
右移 |
变量>>表达式 |
双目运算符 |
||
6 |
> |
大于 |
表达式>表达式 |
左到右 |
双目运算符 |
>= |
大于等于 |
表达式>=表达式 |
双目运算符 |
||
< |
小于 |
表达式<表达式 |
双目运算符 |
||
<= |
小于等于 |
表达式<=表达式 |
双目运算符 |
||
7 |
== |
等于 |
表达式==表达式 |
左到右 |
双目运算符 |
!= |
不等于 |
表达式!= 表达式 |
双目运算符 |
||
8 |
& |
按位与 |
表达式&表达式 |
左到右 |
双目运算符 |
9 |
^ |
按位异或 |
表达式^表达式 |
左到右 |
双目运算符 |
10 |
| |
按位或 |
表达式|表达式 |
左到右 |
双目运算符 |
11 |
&& |
逻辑与 |
表达式&&表达式 |
左到右 |
双目运算符 |
12 |
|| |
逻辑或 |
表达式||表达式 |
左到右 |
双目运算符 |
13 |
?: |
条件运算符 |
表达式1? 表达式2: 表达式3 |
右到左 |
三目运算符 |
14 |
= |
赋值运算符 |
变量=表达式 |
右到左 |
|
/= |
除后赋值 |
变量/=表达式 |
|||
*= |
乘后赋值 |
变量*=表达式 |
|||
%= |
取模后赋值 |
变量%=表达式 |
|||
+= |
加后赋值 |
变量+=表达式 |
|||
-= |
减后赋值 |
变量-=表达式 |
|||
<<= |
左移后赋值 |
变量<<=表达式 |
|||
>>= |
右移后赋值 |
变量>>=表达式 |
|||
&= |
按位与后赋值 |
变量&=表达式 |
|||
^= |
按位异或后赋值 |
变量^=表达式 |
|||
|= |
按位或后赋值 |
变量|=表达式 |
|||
15 |
, |
逗号运算符 |
表达式,表达式,… |
左到右 |
从左向右顺序运算 |
上表中可以总结出如下规律:
结合方向只有三个是从右往左,其余都是从左往右。
所有双目运算符中只有赋值运算符的结合方向是从右往左。
另外两个从右往左结合的运算符也很好记,因为它们很特殊:一个是单目运算符,一个是三目运算符。
C 语言中有且只有一个三目运算符。
逗号运算符的优先级最低,要记住。
此外要记住,对于优先级:算术运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符。逻辑运算符中 “逻辑非 !” 除外。
2、优先级的一些特别说明
上表中,优先级同为 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 |
那么是不是有了上面的总结就稳妥了呢?当然不可能,且不说我们的总结很不完备,就算记住了所有的规则,在使用过程中仍然有可能漏洞百出,最好的办法是养成良好的编码习惯!
3、由优先级引发的错误
优先级问题经常会造成一些意想不到的结果,有的甚至非常严重,而且很难察觉到哪个地方运算符的优先级存在错误。当然,如果能够熟记各种运算符的优先级也许能够避免由运算符的优先级引发的问题,但实际上是很难达到的,C 语言的运算符运用非常灵活,编码的时候不可能时刻关注其优先级。
而且事实上在编程的时候也不需要考虑优先级的问题。因为如果不知道优先级高低的话,加一个括号就可以了,因为括号( )
的优先级是最高的。
简而言之,首先,不需要专门记忆,也没有必要。因为作为初学者,哪个优先级高、哪个优先级低我们很难记住。就算死记硬背记住了,时间长不用也会忘记。所以当一个表达式中有多个运算符时,如果不知道哪个优先级高哪个优先级低就查一下优先级表。用的时间长了自然而然就记住了,这样记才会记得深刻。
其次,还是养成良好的编码习惯和多用多练更靠谱。一定要多调试,光靠看代码,水平是很难提上来的。
附C语言运算符优先级口诀:
括号成员第一; //括号运算符 []() 成员运算符 . ->
全体单目第二; //所有的单目运算符比如 ++、--、+(正)、-(负)、指针运算*、&乘除余三,加减四; 这个"余"是指取余运算即 %
移位五,关系六; //移位运算符:<< >>,关系:> < >= <= 等
等于(与)不等排第七; //即 == 和 !=
位与异或和位或; //这几个都是位运算: 位与 & 、异或 ^ 、位或 |
"三分天下"八九十;
逻辑或跟与; //逻辑运算符:|| 和 &&
十二和十一; //注意顺序:优先级(||) 低于 优先级(&&)
条件高于赋值; //三目运算符优先级排到 13 位只比赋值运算符和","高
逗号运算级最低; //逗号运算符优先级最低
欢迎关注微信公众号『OpenSSR』
C语言应用笔记(一):运算符优先级和使用问题相关推荐
- C语言学习笔记(四) 运算符优先级
C语言中有很多运算符,除了四则运算,还有位运算.比较运算.逻辑运算.赋值运算等等,令人眼花缭乱的同时,优先级也让人头疼.通常建议在写代码的时候不用省略括号,但是并不是所有程序员都会按照这个规矩来,因此 ...
- Java/C语言/C++/Python/PHP运算符优先级
Java 运算符优先级 运算符 优先级 postfix expr++ expr-- unary ++expr --expr +expr -expr ~ ! multiplicative * / % a ...
- C语言重难点:运算符优先级
文章目录 运算符优先级 算数运算符 关系运算符 逻辑运算符 位运算符(点击) 赋值运算符 其他 运算符优先级 括号等>负号.自增减.取地址.解引用.!.sizeof>乘除加减.移位> ...
- C语言1e12怎么识别,掌握C语言中基本的运算符
2.3.7 逗号运算符与逗号表达式 (10) 2.4 数据类型转换 (11) 2.4.1 自动类型转换 (11) 2.4.2 赋值转换 (12) 2.4.3 强制类型转换 (12) 习题二 (13) ...
- C语言学习及应用笔记之一:C运算符优先级及使用问题
C语言中的运算符绝对是C语言学习和使用的一个难点,因为在2011版的标准中,C语言的运算符的数量超过40个,甚至比关键字的数量还要多.这些运算符有单目运算符.双目运算符以及三目运算符,又涉及到左结合和 ...
- 《C语言编程初学者指南》一2.9 理解运算符优先级
本节书摘来自异步社区<C语言编程初学者指南>一书中的第2章,第2.9节,作者[美]Keith Davenport(达文波特) , M1ichael Vine(维恩),更多章节内容可以访问云 ...
- 关于C语言运算符优先级的记忆技巧是什么?
关于C语言运算符优先级的记忆技巧是什么? (1)先(括号)内层,后(括号)外层. (2)先函数,后运算. (3)先算术,后关系,再逻辑. (4)先乘除,后加减. (5)先左,后右. (6)搞不清,加括 ...
- new是不是c语言运算符优先级表,C语言运算符优先级列表(超详细)
<C语言运算符优先级列表(超详细)>由会员分享,可在线阅读,更多相关<C语言运算符优先级列表(超详细)(7页珍藏版)>请在人人文库网上搜索. 1.本篇文章是对C语言中运算符的优 ...
- C 语言运算符优先级
C 语言运算符优先级 优先级 运算符 描述 结合性 1 ++ -- 后缀自增与自减 从左到右 () 函数调用 [] 数组下标 . 结构体与联合体成员访问 -> 结构体与联合体成员通过指针访问 ( ...
最新文章
- 大数据与 AI 生态中的开源技术总结
- buu [AFCTF2018]Morse
- NYOJ 618 追击
- 我设计的简单事务控制
- 剑指Offer - 面试题53 - II. 0~n-1中缺失的数字(二分、位运算)
- Django模型修改及数据迁移
- Pytorch——批标准化(层归一化)
- Project Office 9.0 for mac(任务项目管理软件)
- Sybase获取所有用户表,以及所有者(owner)
- 打开plsqldev报错解决
- 哈尔滨工业大学-计算机系统大作业-程序人生
- AI和数学领域的咖啡甜心(一):DeepFace基础
- Codeforces 934D - A Determined Cleanup
- C#获取中国免费的天气信息
- Arcanist用法简介
- 数据分析-傅里叶变换
- 简单的使用一下增强for循环
- 调用百度api实现驾车路线和时间距离计算
- KSO-vue创建项目以及安装npm与node
- vue项目中scrollTop如何使用
热门文章
- 我的世界服务器修改视野,我的世界默认视野是多少度
- c语言学的是什么,C语言怎么学?
- python 最简单的图灵机器人
- 大型医院信息系统HIS源码 HIS系统全套源码
- 高项-信息系统项目管理师-重要考点
- 图像转换 image translation系列(17)| 最新ICCV2021生成对抗GAN汇总梳理
- redis 失效时间单位是秒还是毫秒_redis键过期时间的应用
- Android TextView文字底部或者中间 加横线
- Android4.4 XML解析死循环异常导致的开机无法正常启动
- Echelon/艾美捷——脂质与蛋白质相互作用的研究