17

我正在尝试找出一些 C 声明。这些 C 声明的含义是什么?

double (*b)[n];
double (*c[n])();
double (*d())[n];
4

4 回答 4

13
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并返回(剩下的都是 void)void。所以 f 是一个指向函数的指针,该函数采用 int 并返回一个 n 指针数组,该数组指向采用 char 并返回 void 的函数

高温高压

于 2012-11-06T08:55:06.950 回答
9

解析C 声明的基本规则是“从右向左阅读,离开一对括号时由内向外跳向右”,即从嵌套最深的一对括号开始,然后向右看。从技术上讲,您必须了解运算符关联性,但它在大多数情况下都足够好用。

现在让我们将此(简化)规则应用于您的问题:


double (*b)[n];
         ^

b 是一个

double (*b)[n];
        ^

指向的指针

double (*b)[n];
           ^^^

和数组

double (*b)[n];
^^^^^^

双打。


double (*c[n])();
         ^^^^

c 是一个数组

double (*c[n])();
        ^

指向

double (*c[n])();
              ^^

职能

double (*c[n])();
^^^^^^

返回双倍。


double (*d())[n];
         ^^^

d 是一个函数

double (*d())[n];
        ^

返回一个指向

double (*d())[n];
             ^^^

一个数组

double (*d())[n];
^^^^^^

双打


在大多数 *nixes 上都有一个简洁的实用程序,称为cdecl,它采用 C 声明字符串并将其转换为自然语言句子。

于 2012-11-06T09:04:05.643 回答
4

让我们试试这个方法。

首先,你应该熟悉这三个符号:

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],则声明变为“双z”

(四)
——什么是“z”?
-------------------------------------------------- ----------------------
重复 (i),我们发现 z 是一个双精度数。
这意味着, d 是一个函数,它返回一个指向 n 个双精度元素的数组的指针。
-------------------------------------------------- ----------------------

让我们看另一个表达式:

无效 (*(*f)(int)[n])(char)
1.
  我们找到 f。
2.
  f 是一个指针。*f -> 一个
  无效 (*a(int)[n])(char)
3.
  a 是一个函数。a() -> b
  无效 (*b[n])(char)
  --f 是指向函数的指针(带有 int 参数)--
4.
  b 是一个数组。b[] -> c
  无效 (*c)(char)
  --f 是一个指向函数的指针,该函数返回一个数组(包含 n 个元素)--
5.
  c 是一个指针。*c -> d
  无效d(字符)
  --f 是一个指向函数的指针,该函数返回一个包含 n 个指针的数组--
6.
  d 是一个返回 void 的函数。
  --f 是一个指向函数的指针,它返回一个包含 n 个指向函数(带有 char 参数)的指针的数组,返回 void--
于 2012-11-06T09:37:53.297 回答
1

有两个很好的资源可以理解“C 胡言乱语”:

cdecl.org 的输出:

  • double (*c[n])(): 语法错误(n此处无效)
  • double (*c[])(): 将 c 声明为指向返回 double 的函数的指针数组
于 2012-11-06T09:09:17.957 回答