这篇博文有没有必要呢?

关于优先级问题,其实也不必太强求,我们提倡使用()来代表优先级,让程序简单易懂,对自己以及对他们都好。可是呢?有的时候你不得不阅读一些劣质的代码,把一些表达式硬生生地写成了玄学!

为了让自己更强大,我们还是总结一下吧,以免遇到!

最后,强调下自己最好不要写这种代码!除非阅读代码的人和你有仇,并且你可自己有仇!

这里声明下,关于一些表达式的解释方式,我是按照《C与指针》中的方法解释的,我在其他博文中也总结了,参看:【 C 】对指针表达式的个人总结与思考


num1:

int  *ap[];

其实我们可以分析下这个声明的含义,首先我们必须先知道下标引用操作符[]的优先级高于间接引用操作符,这样首先ap[]是一个数组,然后对其元素解引用(间接访问),因此我们可以断定这是一个数组,且数组的元素是指针类型,所以这个声明是一个指针数组。

我们改善的写法应该为:

int  *( ap[] );

其实这个例子还比较简单,所以,不加括号也没问题,一个有经验的程序员应该不会误判!

如果我们误以为间接访问操作符*的优先级高于下标引用操作符[],我们就会把这个声明,误判为:int  (*ap)[],如果是这样的话就出大事了,我们来分析下,这个表达式是什么意思?

首先ap是一个指针,对其解引用后呢,又可以进行下标访问操作,可见这是一个指向数组的指针的声明。

关于指针数组和指向数组的指针,二者确实容易混淆,我有相关博文对此进行专门介绍:

【 C 】指针数组案例分析(const的作用)

【 C 】指向数组的指针(数组指针)(行指针)


num2:

int *fp();

这是一个猛一看很令人头疼的声明,fp到底是什么?

我们不妨一起分析下:我们必须知道的优先级关系是函数()高于间接访问*。这样的话,这个表达式首选执行的是fp(),很显然这是一个函数,其次,函数存在一个返回值,对返回值进行解引用(间接访问)得到一个int类型的值,可见,这是一个指针函数,函数的返回值是一个指向int类型的指针常量。

可见,上述表达式这样声明会更容易辨认些:

int *( fp() );

同样,这种表达式怪怪的,也许是因为大家都了解这个优先级别的原因或者函数指针会写成这样的形式:int (*fp)();所以认为不至于混淆!

可是我们常常会误以为这是一个函数指针,也就是把表达式误以为等价于:int (*fp)();我们来分析这个表达式是什么含义:首先执行的是

*fp,那么可以断定fp就是一个指针了,其次又可以进行函数引用(),那么根据我们的知识可知,这是一个指向函数的指针,函数定义过后,是有一个地址专门存放的,那有一个指向该函数的指针也不为过吧。该函数还是一个返回值为int类型的值的函数。

程序中的每个函数都位于内存中的某个位置,所以存在指向那个位置的指针是完全可能的 --------------------- 本文来自 李佳姗 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/Reborn_Lee/article/details/82694875?utm_source=copy

关于函数指针,我也有专门的博文介绍:【 C 】初识函数指针


num3

(val & mask != 0)

多少人会和我一样认为是这样的呢?(val & mask) != 0。

这是不对的,它的真正含义是: val & (mask != 0),这是因为== 和 != 的优先级高于位操作符。

可见,如果写成:

val & (mask != 0)

可读性会更高 。这也正是我们所提倡的写法。


num4

c = getchar() != EOF

我们可能会认为其等价于:

( c = getchar() ) != EOF

其实不然,因为==和!=的优先级高于赋值操作符,它等价于:

c =( getchar() != EOF)


num5

msb << 4 + lsb

写成这个样子真的很无奈,它让我们无法判别,我们可能会以为它等价于:

(msb << 4)+ lsb

但事实上,算术操作符的优先级高于移位操作符,所以它等价于:

msb << (4 + lsb)


num6

逗号运算符在所有操作符中优先级最低,所以如下表达式:

i = 1, 2

等价于:

(i = 1), 2


num7

*p.f

.的优先级高于*,所以等价于

*(p.f)

即对p取f偏移,作为指针,然后进行间接访问。

p应该是一个结构体变量,然后直接访问对结构成员进行访问p.f,由于成员是一个指针,所以对其进行间接访问操作得到该指针指向的值。

这个表达式让我们明白,我们不要把这个表达式等价成了这个:

(*p).f

首先,p是一个指向结构变量p的指针,然后对其解引用,得到结构体变量,然后间接访问其成员。这个过程看起来很不直观,为了解决这个问题,我们引入了结构体的间接访问->,用:

p ->f

来清晰的表达。

【 C 】最容易误判的优先级问题相关推荐

  1. 科创人·StreamNative翟佳:开源模式价值为王,基础软件的未来在国内社区

    翟佳,StreamNative 联合创始人 Apache Pulsar 和 Apache BookKeeper PMC 成员,前 EMC 统一存储部门技术负责人,前 Streamlio 创始工程师.2 ...

  2. 基于c语言优先级病房呼叫_C语言

    数据类型关键字 基本数据类型(5个) void:声明函数无返回值或无参数,声明无类型指针,显示丢弃去处结果 char:字符型类型数据,属于整型数据的一种 int:整型数据,通常为编译器指定的机器字长 ...

  3. 运算符优先级记忆口诀及列表(转)

    C语言运算符优先级和口诀 一共有十五个优先级: 同一优先级的运算符,运算次序由结合方向所决定 1   ()  []  .  ->        (括号,成员排第一) 2   !  ~   -(负 ...

  4. 优先级队列实现哈夫曼树的编码和译码

    //优先级队列实现的哈夫曼树的编码和译码 #include<iostream> #include<queue> #include<string> using nam ...

  5. C# 运算符的优先级

    优先级由高到低 ++ --(用作前缀); + ; -(一元); () ; ! ; ~ * ; / ; % + ; - <<; >> < ; > ; <= ; ...

  6. linux+任务默认优先级,uclinux内核的任务优先级及其load_weight

    快乐虾 http://blog.csdn.net/lights_joy/ lights@hb165.com 本文适用于 ADSP-BF561 uclinux-2008r1.5-RC3(移植到vdsp5 ...

  7. 使用最小堆使用优先级队列(c语言版本)

    下面的例子来自Weiss的<数据结构与算法分析:c语言描述>,自己亲自敲了一遍,跑了个demo,并将结果记录下来. binheap.h的头文件声明 //description: 使最小堆实 ...

  8. 3G重选至4G--基于优先级

    3G重选至4G--基于优先级 1.      Specification 1.1  Measurementrules 是否需要开启测量 3GPP 25.304 - 5.2.6.1.2aMeasurem ...

  9. 邮件发送类,支持HTML格式,支持优先级设置

    www.chinacs.net  2002-5-9  中文C#技术站 邮件发送类,支持HTML格式,支持优先级设置.通过SOCKET类实现的 using System; using System.Te ...

最新文章

  1. 【Linux】Linux 目录结构
  2. 讲讲Bootstrap是在干啥?
  3. dotNET Core实现分布式环境下的流水号唯一
  4. 数据结构与算法————稀疏数组
  5. 信号完整性与电源完整性分析_电源完整性,信号完整性,你说哪个更重要一点?...
  6. 中嵌套的页面如何操作父页面_UI设计中签到页面如何设计
  7. Spring 的 BeanPostProcessor接口实现
  8. 网易云音乐服务器code521,网易云音乐scode500是怎么回事 网易云音乐scode502怎么解决...
  9. 2018百度seo最新算法大全 青岛墨羽SEO统计
  10. pythonalist是什么意思_3. Python3轻食丨一个故事看懂List所有用法:1年级1班的班级生活...
  11. 腾讯,字节等大厂面试真题汇总,赶快收藏备战金九银十!
  12. 代码没问题但运行不出来
  13. NetLimiter Pro
  14. 2.1 压力泊松方程(OpenFOAM理论笔记系列)
  15. 以神奇“三”为本的逻辑与指号学----皮尔斯逻辑之三
  16. 什么是dB?为什么要用dB?dB家族成员有哪些?
  17. 跟我一起从零学习安卓逆向分析
  18. 清除flashback日志
  19. Zeus: Uber 开发的分布式的高扩展 Shuffle 服务组件
  20. 【RK3288 Android 7.1 / KEN】双屏异显流程

热门文章

  1. winsock I/O模型
  2. django前端引用数据_「基于Python技术的智慧中医商业项目」Django前端网站篇-5.资讯的数据交互...
  3. python任务队列 http_基于Python开发的分布式任务队列:Celery
  4. python装饰器实现aop_python中面向切片编程(AOP)和装饰器
  5. 织梦 PHP 字段 调用,织梦dede网站内容模型普通文章调用自定义图片字段的方法(和调用...
  6. 第十七届全国大学智能车竞赛赛区划分
  7. DevEBox STM32F4x1开发板 设置MicroPython STM32F401CC/TM32F411CE STM32F4x1 核心板 开发板 MicroPython
  8. 第十五届智能车竞赛技术报告-成电金秋-AI电磁
  9. 第十五届全国大学生智能汽车竞赛 车模检查手册
  10. freertos 创建互斥量_STM32CubeMX+FreeRTOS学习[6] 互斥量(Lu)