c - C 声明符理解

c - C 声明符理解

...复杂声明符的绑定

这是规范中的一个非常好的提示。

规则本身真的很难分析,因为它是递归的。声明和声明符的关系和部分也是相关的。

结果是:

()and[]是最里面的直接声明符部分,在左边声明(直接通过符号)函数和数组名称

*将名称声明为右侧的指针

(...) 对于...复杂的情况需要更改默认关联。

分组括号引导您从内部(标识符)到外部(左侧的类型说明符,例如“int”)。

最后,这一切都与指针符号*及其所指的内容有关。重新制定的(括号表示可选,这里不是数组!)语法是:

declarator: [* [qual]] direct-declarator

direct-declarator: (declarator)

foo()是 DD(直接声明者)

*foo是一个声明者。(“间接”演绎)

*foo()是 *(foo())。foo 保持一个函数, () 和 [] 绑定最强。* 是返回类型。

(*foo)()使 foo 成为指针。一到一个功能。

顺便说一句,这也解释了为什么在声明者列表中。

int const * a, b

两者都是 const int,但只是a一个指针

const 属于 int,star 只属于 a。这样就更清楚了,

const int x, *pi

但这已经是边缘混淆了。就像现代诗歌一样。适合某些场合。

即使没有括号,解析也会有轻微的掉头。但这很自然:

3 2 0 1

int *foo()

这种标准情况(和类似情况)必须很简单。还有著名的多维数组,如 int a[10][10][10]。

3 1 0 2

int (*foo)()

这里的括号强制“foo”是左侧的内容(指针)。

复杂的声明在 K&R C 书中有自己的章节。

这是一种最简单的复杂声明:

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

它调试到抽象类型:

int (*(*)[])()

替换(*)为:

int (*F[])()

缺少的数组大小会给出编译器警告 - “假设一个元素”。

作为抽象类型:

int (*[])()

但:

int *G[]()

--> 错误:将“G”声明为函数数组

是的,你可以,甚至递归,但使用* 间接和括号。这样就形成了一个洋葱,中间是identifeir,左边是星星,右边是[]和()。

C11 规格有这个怪物。...声明可变参数:

int (*fpfi(int (*)(long), int))(int, ...)

删除所有参数后:

int (*fpfi())()

只是一个返回指针的函数。一个返回 int 的函数。

但是 fpfi 的第一个参数是一个函数本身 - 一个指向具有返回类型的函数的指针和它自己的参数:

int (*)(long)

非抽象的:

int (*foo)(long)

一个指向函数的指针,该函数正式将 long 转换为 int。

那是参数。仅有的。返回值也是一个函数指针,指向函数的参数和返回类型在最外层。删除整个内部功能(int (*)(long), int):

int (*pfi)(int, ...)

或更通用/不完整:

int (*pfi)()

“T(D)”洋葱法则

所以这个洋葱游戏会重演。[]在 和 之间由内而外()和左右左右*。语法不是问题,而是语义。

相关推荐

dnf制裁多久会刷新
beat365在线体育访问不了

dnf制裁多久会刷新

📅 09-25 👁️ 1315
2009 年福特嘉年华二手车怎么样?
365游戏大厅网址

2009 年福特嘉年华二手车怎么样?

📅 07-13 👁️ 5758
秦始皇的亲妈为什么敢和嫪毐生两个孩子?
beat365在线体育访问不了

秦始皇的亲妈为什么敢和嫪毐生两个孩子?

📅 10-12 👁️ 5182