`
guoyiqi
  • 浏览: 1002231 次
社区版块
存档分类
最新评论

c指针解读之左右法则(转自:http://blog.csdn.net/cattycat/article/details/5660353#quote)

 
阅读更多
C指针声明解读之左右法则
C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:
The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.

这段英文的翻译如下:

右左法则:首先从最里面的圆括号内未定义的标识符开始阅读看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

  总之对声明进行分析,最根本的方法还是按优先级和结合性来类比替换,从那些最基本的声明进行类比,简化,从而进行理解。下面分析几个例子,来具体阐述如何使用这种方法。

#1:int* (*a[5])(int, char*);

  首先看到标识符名a,"[]"优先级大于"*",a与"[5]"先结合。所以a是一个数组,这个数组有5个元素,每一个元素都是一个指针,指针指向"int* (int, char*)",很明显,指向的是一个函数,这个函数参数是"int, char*",返回值是"int*"。OK,结束了一个。:)

#2:void (*b[10]) (void (*)());

  b是一个数组,这个数组有10个元素,每一个元素都是一个指针,指针指向一个函数,函数参数是"void (*)()"【注:这也是一个函数指针, 参数为空,返回为void】,返回值是"void"。完毕!

#3:int(*)() (*c)[9];

   c是一个指针,指针指向一个数组,这个数组有9个元素,每一个元素都是"int(*)()"(也即一个函数指针,指向一个函数,这个函数的参数为空,返回值是int型)。


#4:int (*(*d)[5])(int *);

(*d)------指针;
(*d)[5]------这个指针指向一个数组;
*(*d)[5]------这个数组中每个元素都是指针类型;
int (int *)------ 什么类型的指针?这个类型的。


#5:int (*(*e)(int *))[5];
*e-----向右遇到括号,向左遇到*,说明e是个指针,啥指针呢?
(*e)(int *)------跳出括号向右遇到(int *),说明这个指针是个函数指针,形参为int*, 返回值为何?且听下回分解:);
*(*e)(int *)------返回值为何?向右遇到括号,再向左,喔,遇到*了,那就是返回了一个指针了。啥指针呢? 同样地,下回分解;
(*(*e)(int *))[5]-------向右遇到[],说明那是个指向数组的指针,是啥数组呢?不急,慢慢来;
int (*(*e)(int *))[5]-------向左遇到int,喔,明白了,就是个简单的整型数组。OVER


当然实际当中,当需要声明一个复杂指针时,如果把整个声明写成上面所示的形式,对程序可读性将是一个巨大损害。谁要是写出这样BT的指针声明,那就真是丢rp了,估计会被骂死!。
还是用typedef来对声明逐层分解替换下吧,增强可读性。

例如对于上面的声明:int (*(*func)(int *))[5]; 可以这样分解:
typedef int (*pArr)[5];
typedef pArr (*func)(int *);
这样就容易读得多了啊!


再看看这个啥意思? typedef int (* (* (*FUNC)(int *) )[5] )(int *); ---- 晕了吧。

其实typedef int (* (* (*FUNC)(int *) )[5] )(int *);
等价与下面的:)

typedef int (*PF)(int *);

typedef PF (*PARRAY)[5];

typedef PARRAY (*FUNC)(int *);

(*(void (*)())0)();------->这个呢?
按左右法则:
(void (*)()) -----是一个返回值为void,参数为空的函数指针原型。
  (void (*)())0-----把0强转成一个返回值为void,参数为空的函数指针,指针指向的地址为0.
  *(void (*)())0-----前面加上*表示整个是一个返回值为void的函数的名字
  (*(void (*)())0)()------这当然就是一个函数调用了。

再typedef化简下:
typedef void (*pf)();
(*(pf)0)();
分享到:
评论

相关推荐

    https://download.csdn.net/download/p_xiaojia/9756173

    在C#中,由于其安全性考虑,默认情况下并不支持指针操作,但在特定场景下(如底层编程等),可以通过开启`unsafe`上下文来使用指针。上述代码在C#中的实现方式为: ```csharp unsafe { int a; int* pa = &a; }...

    主要讲述以http://blog.csdn.net/LCL_data/archive/2009/12/09/4974499.aspx中的链表逆序为模板来讲述指针的使用

    主要讲述以http://blog.csdn.net/LCL_data/archive/2009/12/09/4974499.aspx中的链表逆序为模板来讲述指针的使用

    android studio jni开发 案例代码

    Android Studio JNI开发是Android应用程序开发中的一个重要组成部分,它允许开发者使用C++或其他本地语言编写部分代码,以实现高性能计算、利用硬件加速或者调用已有的C/C++库。JNI(Java Native Interface)是Java...

    二叉树操作合集 相关文章:https://blog.csdn.net/weixin_42708321/article/deta

    1. **创建二叉树**:首先,我们需要定义一个结构体来表示二叉树的节点,包括数据域(存储信息)和两个指针域(指向左右子节点)。然后通过动态分配内存来创建新节点。 2. **插入节点**:插入操作分为两种情况:根...

    FPGA实现 异步FIFO + 同步FIFO 的工程源码

    基于Intel(Altera)的Quartus II平台(复制一下就...3、更详细的说明请参考本人博文《https://wuzhikai.blog.csdn.net/article/details/121136040》及《https://wuzhikai.blog.csdn.net/article/details/121152844》。

    滑动刻度尺滑动刻度尺。详情 有图有真相 http://blog.csdn.net/liudao7994/article/det

    它通常表现为一条带有可移动指针的条形图,用户可以通过滑动指针来设定值。在iOS、Android以及许多其他平台的开发中,滑动刻度尺都有相应的API支持。 在iOS中,滑动刻度尺被称为UISlider,它是UIControl的一个子类...

    C语言大作业学生成绩管理系统

    此实验需要在CodeBlocks等C语言编译平台上完成同时本实验要求所写的程序可以流畅的在编译平台上运行。首先为用户提供一个菜单,展示各个选项的功能,用户可输入一个选项(数字),执行相应的功能,通过运用switch...

    崩坏3桌面端游戏鼠标(光标) #资源分享 #鼠标 #光标 #崩坏 #游戏 #自定义 #电脑美化

    崩坏3桌面端游戏鼠标(光标),已优化,有各种状态的切换(如文字、移动、繁忙、无响应、工作等状态),已经过光标热点校准,还有“德莉傻”彩蛋,崩坏玩家的回忆,电脑美化必备,...https://blog.csdn.net/qq_51273504/

    霓虹线条鼠标指针方案资源下载

    https://blog.csdn.net/dearmite/article/details/132224055 样子在这篇文章里。 配套资源 后端 小程序轮播图的两种后台方式(jsp)-jsp https://download.csdn.net/download/dearmite/88111567 前端 小程序从轮播图到...

    win7自带阵阵做的左手指针(有bug,下载修正版http://download.csdn.net/source/3390149)

    为了解决这些bug,作者提供了修正版的链接(http://download.csdn.net/source/3390149),用户可以通过下载这个修正版来改善上述问题。这表明社区中的开发者或爱好者会通过共享他们的修复方案来帮助其他用户解决此类...

    JNI文档资料源码_2020_01_28.zip

    博客地址 : https://hanshuliang.blog.csdn.net/article/details/104083928 I . jintArray 类型说明 II . jboolean 类型说明 III . GetIntArrayElements 方法解析 ( jintArray -> jint* | int* ) IV . jarray...

    C语言C++全套资料(含练习项目)

    在IT领域,C语言和C++是两种非常重要的编程语言,尤其对于初学者而言,它们是进入计算机科学世界的基石。C语言以其简洁高效的特点被广泛应用于操作系统、嵌入式系统和底层开发,而C++则在此基础上加入了面向对象的...

    数据结构课程设计-客运订票系统

    数据结构课程设计——客运订票系统 数据结构课程设计使用了数组、指针、链表及结构体等等。 客运订票系统主要实现以下功能: ...具体见博客:https://blog.csdn.net/weixin_46703995/article/details/121171346

    Advanced C Tips and Techniques.pdf

    #### 标题:高级C语言编程技巧(Advanced C Tips and Techniques) #### 描述: 本资料提供了一系列关于C语言的深入理解与高级技术应用指南。它不仅包含了对C语言核心概念的深入剖析,还涵盖了实际编程中的最佳实践...

    经典才c/c++游戏源代码

    在IT领域,编程语言是构建各种软件和游戏的基础,C和C++作为两种非常重要的编程语言,具有高效、灵活和底层控制的特点。本资源“经典才C/C++游戏源代码”是一个集合,包含了使用C和C++语言编写的经典游戏的源代码。...

    11.5 指针操作.7z

    在描述中提到了博客源码的链接:“https://blog.csdn.net/u014411348/article/details/110199522”,这可能是一个CSDN博主分享的关于指针操作的教程或示例代码。通过访问这个链接,我们可以获得更详细的讲解和实践...

    http://baiy.cn/doc/cpp/index.htm#代码风格与版式_函数

    博客链接虽然不可用,但我们可以推测该博客可能详细介绍了C++的编码实践,包括但不限于函数命名、参数列表、注释规则、空指针的使用等方面。这些内容通常会包含函数的命名约定(如驼峰式或下划线式),参数的默认值...

    基于C++的图像的最优缩放(图像放大缩小).zip

    资源包含文件:设计报告word+源码及可执行EXE文件 本系统通过用一个二维矩阵来描述一个单通道图像的数据,从而...详细介绍参考:https://biyezuopin.blog.csdn.net/article/details/122802257?spm=1001.2014.3001.5502

    org.apache.commons.net.ftp jar包及FTP调用例子

    上传了收集的最新的 commons-io-2.4.jar 包 和 commons-net-3.3.jar 以及 FTP java调用例子。net 包是一个用于操作Internet基础协议(Finger,Whois,...它使得开发者不再需要直接面对各种协议的Socket级的低层命令。

Global site tag (gtag.js) - Google Analytics