C语言指针右左法则

栏目: C · 发布时间: 4年前

内容简介:对于一些复杂的声明式,我们往往很难理解它代表的含义,“右左法则“是前辈们总结出的一套分析规则,借助它,可以准确快速地分析出上式的具体含义。一个声明式可以分为两部分,“basic type”和“derived types”,如下,

对于一些复杂的声明式,我们往往很难理解它代表的含义,

int (*(*(*foo)(int*))[5])(int*); /* complex and difficult to understand */

“右左法则“是前辈们总结出的一套分析规则,借助它,可以准确快速地分析出上式的具体含义。

一:声明式的组成

一个声明式可以分为两部分,“basic type”和“derived types”,如下,

C语言指针右左法则

对于“derived types”,它主要由以下几部分组成,

foo ,标识符。

* ,pointer to... ,指针符号。

[] ,array of... ,表示数组的一对方括号。注意方括号内也可以有个数字,例如 [10] ,那么它的含义就是"array of 10..."。

() ,function returning... ,表示函数名后面包住参数的一对括号。注意括号内也可以有参数,例如 (int*) ,那么它的含义就是“function with parameter 'int*' returning...”。

二:右左法则

根据运算符优先级,"array of" [] 和"function returning" () 的优先级比"pointer to" * 高,因此定义的规则如下:

  1. 总是以标识符为开头,

    foo is ...

  2. 总是以“basic type”为结尾,

    foo is ... char

  3. 中间部分比较复杂,但有一个规律,

    “go right when you can, go left when you must”

接下来我们就分别以一易一难两个例子具体讲下这个“右左法则”。

三:简单的例子

long **foo[7];

我们一步一步地按照上面的“右左法则”来,

  • long * * foo

    [7]

    以标识符为开头,以“basic type”为结尾,

    foo is ... long

  • long

    * *

    foo [7]

    根据“右左法则”的“go right when you can“,下一步是分析”array of 7...“ [7]

    foo is array of 7 ... long

  • long * * foo [7]

    已走到右边的尽头,故“go left when you must”,下一步分析指针符号 *

    foo is array of 7 pointer to ... long

  • long * * foo [7]

    继续“go left when you must”,依旧是一个指针,

    foo is array of 7 pointer to pointer to long

  • long * * foo [7]

    全部分析完毕,完整的含义为: foo is array of 7 pointer to pointer to long ,翻译为:foo是一个长度为7的数组,这个数组的元素是指向long型指针的指针。

四:复杂的例子

int (*(*(*foo)(int*))[5])(int*);
  • int ( * ( * ( * foo

    ) ( int* ) ) [5] ) ( int* )

    以标识符为开头,以“basic type”为结尾,

    foo is ... int

  • int ( * ( * ( * foo

    ) ( int* ) ) [5] ) ( int* )

    走到括号尾,故“go left when you must”,下一步分析指针符号 *

    foo is pointer to ... int

  • int

    ( * ( *

    ( * foo ) ( int* )

    ) [5] ) ( int* )

    一对括号内的内容分析完,继续“go right when you can“,下一步分析 (int*)

    foo is pointer to function with parameter 'int*' returning ... int

  • int ( * ( * ( * foo ) ( int* )

    ) [5] ) ( int* )

    走到括号尾,故“go left when you must”,下一步分析指针符号 *

    foo is pointer to function with parameter 'int*' returning pointer to ... int

  • int

    ( *

    ( * ( * foo ) ( int* ) ) [5]

    ) ( int* )

    此时可以“go right when you can“,下一步分析 [5]

    foo is pointer to function with parameter 'int*' returning pointer to array of 5 ... int

  • int ( * ( * ( * foo ) ( int* ) ) [5]

    ) ( int* )

    走到括号尾,故“go left when you must”,下一步分析指针符号,

    foo is pointer to function with parameter 'int*' returning pointer to array of 5 pointer to ... int

  • int ( * ( * ( * foo ) ( int* ) ) [5] ) ( int* )

    此时可以“go right when you can“,下一步分析 (int*)

    foo is pointer to function with parameter 'int*' returning pointer to array of 5 pointer to function with parameter 'int*' returning int

  • int ( * ( * ( * foo ) ( int* ) ) [5] ) ( int* )

    全部分析完毕,完整的含义为: foo is pointer to function with parameter 'int*' returning pointer to array of 5 pointer to function with parameter 'int*' returning int ,翻译为:foo是一个函数指针,这个函数的参数是“int*”,返回的是一个指向长度为5的数组的数组指针,这个数组的元素也是函数指针,参数也是“int*”,返回的是“int”。

五:抽象声明式(Abstract Declarators)

抽象声明式(Abstract Declarators)通常用作数据类型转换和作为 sizeof 的参数,与上面几个声明式不同的是,抽象声明式缺少 标识符

int (*(*)())()

“右左法则”都是从标识符开始分析的,那么问题来了,抽象声明式没有标识符,该从哪里开始呢? 找到它应该在的位置

我们仔细地观察,会发现,不管是什么声明式,标识符满足下面几条规律:

*
[]
()

根据这几条规律,我们再来看看上面的抽象声明式。根据规律1和规律3,可以锁定大致范围,

int ( * ( *

• ) •

( ) ) ( )

其中“•”这个点就代表标识符应该在的位置,再根据规律4,最终锁定在左边那个“•”的位置,那么这个抽象声明式我们可以看成这样,

int (*(*foo)())()

如此,我们就可以很容易地知道它的含义了, foo is pointer to function returning pointer to function returning int

六:调用约定(Calling Conventions)

在Windows平台上的Win32编程中,我们经常会碰到一些调用约定符号 __cdecl,__fastcall__stdcall 等等,

extern int __cdecl main(int argc, char **argv);

extern BOOL __stdcall DrvQueryDriverInfo(DWORD dwMode, PVOID pBuffer, DWORD cbBuf, PDWORD pcbNeeded);

这些调用约定符号是用来修饰函数的,所以若出现在声明式中,我们应当将其置于“function returning” () 之前,比如,

BOOL (__stdcall *foo)();

它的含义为: foo is pointer to __stdcall function returning BOOL


以上所述就是小编给大家介绍的《C语言指针右左法则》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大象无形:虚幻引擎程序设计浅析

大象无形:虚幻引擎程序设计浅析

罗丁力、张三 / 电子工业出版社 / 2017-4 / 65

《大象无形:虚幻引擎程序设计浅析》以两位作者本人在使用虚幻引擎过程中的实际经历为参考,包括三大部分:使用C++语言进行游戏性编程、了解虚幻引擎本身底层结构与渲染结构、编写插件扩展虚幻引擎。提供了不同于官方文档内容的虚幻引擎相关细节和有效实践。有助于读者一窥虚幻引擎本身设计的精妙之处,并能学习到定制虚幻引擎所需的基础知识,实现对其的按需定制。 《大象无形:虚幻引擎程序设计浅析》适合初步了解虚幻......一起来看看 《大象无形:虚幻引擎程序设计浅析》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具