搞清楚C声明
我对C很新,我想弄清楚一些C声明。 有人可以帮我解释这些C声明的含义吗?
double (*b)[n]; double (*c[n])(); double (*d())[n];
我很感激帮助!
double (*b)[n];
b是指向n个双精度数组的指针
double (*c[n])();
c是一个指向函数的n个指针的数组,这些函数接受未指定数量的参数并返回double
double (*d())[n];
d是一个函数,它接受未指定数量的参数并返回一个指向n个双精度数组的指针
通常,为了解析这些声明,请采取以下方法。 例如,让我们看看最后一个声明
double (*d())[n];
对d做的第一件事是什么? 它用()调用,因此它是一个函数 , 它采用了未指定数量的参数和returnig …结果做了什么? 它被解除引用(*),因此它是一个指针 。 结果然后被索引,因此它是一个n的数组 ……剩下的是什么? 一双,因此双打 。 以粗体阅读部分,您将得到答案。
让我们看另一个例子
void (*(*f)(int)[n])(char)
这里首先取消引用f ,因此它是一个指针 …然后用(int)调用它,因此一个函数接受int并返回 ,然后用[n]索引结果,所以n的数组 。 结果再次被取消引用,所以指向 。 然后结果由(char)调用,所以函数采用char并返回(all is left is void) void 。 所以f是一个指向函数的指针,该函数接受int并返回一个n指针数组,这些指针指向带有char和返回void的函数 。
HTH
解析C声明的基本规则是“从右到左阅读,当留下一对括号时,向内跳出右边”,即启动最深嵌套的括号对,然后自己向右看。 从技术上讲,您必须了解操作员关联性,但在大多数情况下它运行良好。
现在,我们将此(简化)规则应用于您的问题:
double (*b)[n]; ^
b是一个
double (*b)[n]; ^
指向
double (*b)[n]; ^^^
和数组
double (*b)[n]; ^^^^^^
双打。
double (*c[n])(); ^^^^
c是一个数组
double (*c[n])(); ^
指向
double (*c[n])(); ^^
function
double (*c[n])(); ^^^^^^
返回双倍。
double (*d())[n]; ^^^
d是一个函数
double (*d())[n]; ^
返回指针
double (*d())[n]; ^^^
一个数组
double (*d())[n]; ^^^^^^
双打
在大多数* nix上都有一个简洁的实用工具,称为cdecl ,它接受一个C声明字符串并将其转换为自然语言句子。
试试这个。
首先,你应该熟悉这三个符号:
1. * - 一个指针。 2. [] - 一个数组。 3.() - 一个函数。(注意:不是括号)
我们以“double(* d())[n]”为例。
第一步是在声明中找出标识符,标识符是变量的名称,这里是“d”。
(一世) - 什么是“d”? -------------------------------------------------- ---------------------- 查看标识符的右侧,查看是否有“[]”或“()”: ... d [] ...:d是一个数组。 ... d()...:d是一个函数。 如果两者都没有,请向左侧看,看是否有“*”: ...... * d ......:d是一个指针。 -------------------------------------------------- ----------------------
现在我们发现d是一个函数。 使用x代替d(),然后声明变为“double(* x)[n]”
(ⅱ) - 什么是“x”? -------------------------------------------------- ---------------------- 重复(i),我们发现x是一个指针。 这意味着,d是一个返回指针的函数。 -------------------------------------------------- ----------------------
使用y替换* x,然后声明变为“double y [n]”
(ⅲ) - 什么是“y”? -------------------------------------------------- ---------------------- 重复(i),我们发现y是n个元素的数组。 这意味着,d是一个返回指向n个元素数组的指针的函数。 -------------------------------------------------- ----------------------
用z代替y [n],然后声明变成“double z”
(ⅳ) - 什么是“z”? -------------------------------------------------- ---------------------- 重复(i),我们发现z是双重的。 这意味着,d是一个返回指向n个双元素数组的指针的函数。 -------------------------------------------------- ----------------------
让我们看另一个表达式:
void(*(* f)(int)[n])(char)
1。 我们找到了f。 2。 f是一个指针。 * f - > a void(* a(int)[n])(char) 3。 a是一个function。 a() - > b void(* b [n])(char) --f是一个指向函数的指针(带有一个int参数) - 4。 b是一个数组。 b [] - > c void(* c)(char) --f是一个返回数组的函数的指针(由n个元素组成) - 5。 c是一个指针。 * c - > d void d(char) --f是一个指向返回n个指针数组的函数的指针 - 6。 d是返回void的函数。 --f是一个指向函数的指针,该函数返回一个指向函数的n个指针数组(带有一个char参数)返回void--
有两个很好的资源来理解“C乱码”:
- http://cdecl.org/ – 翻译“C gibberish↔English”的在线服务
- 大卫安德森的“顺时针/螺旋规则” ,如果你想了解更好的是什么
cdecl.org的输出:
-
double (*c[n])()
:语法错误(n
在这里无效) -
double (*c[])()
:将c声明为函数返回double的指针数组