搞清楚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的指针数组