理解C声明

时间:2014-01-23 03:37:38

标签: c declaration

以下是C声明的列表以及它们代表的类型的描述:

int i;          an int
int *p;         an int pointer
int a[];        an array of ints
int f();        a function returning an int
int **pp;       a pointer to an int pointer
int (*pa)[];        a pointer to an array of ints
int (*pf)();        a pointer to a function returning an int
int *ap[];      an array of int pointers
int aa[][];     an array of arrays of ints
int af[]();     an array of functions returning an int (ILLEGAL)
int *fp();      a function returning an int pointer
int fa()[];     a function returning an array of ints (ILLEGAL)
int ff()();     a function returning a function returning an int
                (ILLEGAL)
int ***ppp;     a pointer to a pointer to an int pointer
int (**ppa)[];      a pointer to a pointer to an array of ints
int (**ppf)();      a pointer to a pointer to a function returning an int
int *(*pap)[];      a pointer to an array of int pointers
int (*paa)[][];     a pointer to an array of arrays of ints
int (*paf)[]();     a pointer to a an array of functions returning an int
                (ILLEGAL)
int *(*pfp)();      a pointer to a function returning an int pointer
int (*pfa)()[];     a pointer to a function returning an array of ints
                (ILLEGAL)
int (*pff)()();     a pointer to a function returning a function
                returning an int (ILLEGAL)
int **app[];        an array of pointers to int pointers
int (*apa[])[];     an array of pointers to arrays of ints
int (*apf[])();     an array of pointers to functions returning an int
int *aap[][];       an array of arrays of int pointers
int aaa[][][];      an array of arrays of arrays of ints
int aaf[][]();      an array of arrays of functions returning an int
                (ILLEGAL)
int *afp[]();       an array of functions returning int pointers (ILLEGAL)
int afa[]()[];      an array of functions returning an array of ints
                (ILLEGAL)
int aff[]()();      an array of functions returning functions
                returning an int (ILLEGAL)
int **fpp();        a function returning a pointer to an int pointer
int (*fpa())[];     a function returning a pointer to an array of ints
int (*fpf())();     a function returning a pointer to a function
                returning an int
int *fap()[];       a function returning an array of int pointers (ILLEGAL)
int faa()[][];      a function returning an array of arrays of ints
                (ILLEGAL)
int faf()[]();      a function returning an array of functions
                returning an int (ILLEGAL)
int *ffp()();       a function returning a function
                returning an int pointer (ILLEGAL)

我们在计算机科学课程中将其作为一种学习指南。我无法理解解释符号的顺序。

例如,

int (*apf[])();     an array of pointers to functions returning an int

您将如何解释和理解该声明?

编辑:

当所有其他函数声明都是非法的时(除非它们是指向函数的指针),为什么函数声明返回指向int指针的指针是合法的?

int **fpp();        a function returning a pointer to an int pointer

5 个答案:

答案 0 :(得分:2)

大多数函数声明都是非法的,因为在C中,函数不允许返回函数或数组。

答案 1 :(得分:1)

在声明中,[]()运算符在*之前绑定;也就是说,*a[]被解析为*(a[])*f()被解析为*(f())。因此,如果要声明指向数组的指针或指向函数的指针,则必须使用括号强制*运算符在[]()运算符之前绑定到标识符,例如(*a)[](*f)()

读取声明的基本规则是从最左边的标识符开始,然后逐步解决,记住上面的优先规则。因此,声明在

int (*apf[])(); 

分解如下

      apf         -- apf
      apf[]       -- is an array
     *apf[]       -- of pointers to 
    (*apf[])()    -- function returning
int (*apf[])();   -- int

语言定义的工件是函数不能返回数组类型或其他函数类型,也不能声明函数类型的数组。这些限制不是任意的;它们是语言如何处理数组和函数表达式的自然结果,但是一个有意义的详细解释将花费更多的时间和更清晰的头脑,而不是我现在可以投入的。

答案 2 :(得分:0)

  

例如,

int (*apf[])();     an array of pointers to functions returning an int
     

您将如何解释和理解该声明?

K& R,附录A,第8.4节,声明者的含义:

  

每个声明符都被认为是一个断言,当一个构造与声明符相同的表单出现在表达式中时,它会产生一个指定类型和存储类的对象。

所以,

  • apf是变量的标识符,我可以使用它进行索引:apf[0]。所以这是一个数组。
  • 使用这样一个数组的元素我可以*apf[0]。所以它是一个指针数组,因为元素可以被解引用。
  • 每个这样的解引用指针我都可以(*apf[0])()。所以,因为我可以调用这样一个数组的解引用元素,它是一个指向函数的指针数组。
  • 每个这样一个没有参数的调用,给出int。因此,它是一个函数指针数组,不带参数并返回int

  

为什么这个函数声明返回一个指针   当所有其他函数声明都是非法的时,int指针合法   (除非它们是函数的指针)?

int **fpp();        a function returning a pointer to an int pointer

如果在任何声明中有一个关于返回函数或数组的步骤,那么它是一个无效的声明,因为它只是不允许在C中返回它。通过相同的方式,您不能声明可以分配的函数或数组变量,就像普通变量一样。尽管如此,您可以为数组和函数声明指针,这是另一回事。

答案 3 :(得分:0)

此声明

int (*apf[])();

指向返回int

的函数的指针数组

表示如果数组已分配存储,则apf[0]apf[1] ETC中指向的函数。不要接受任何参数并返回int

我没见过没有 BOTH 显式大小或初始化列表的数组声明。 如果省略数组大小,我使用的C编译器将只为其分配足够的存储空间 提供的列表(在这种情况下没有)。

因此,不要假设数组已分配存储空间(除非您确定编译器 表现不然)。

答案 4 :(得分:0)

解释非常复杂,我将如何解释:

遵循以下规则:

*

  
      
  1. 始终以变量或函数名称开头。
  2.   
  3. 向右移动直到你得到一个; (你需要优先考虑大括号,即你需要在遇到右大括号时停止)
  4.   
  5. 然后阅读变量左侧的剩余部分。
  6.   
  • 现在举个例子:

示例1: int * ap []

从变量开始并向右移动: ap是一个数组

然后阅读变量左侧的剩余部分: 指向int的指针

结合我们得到的一切: ap是一个指向int的指针数组

示例2: int(* pa)[];

从变量开始: pa是一个指针

然后向右移动: 到数组

然后变量的左侧部分: 整数

合并你得到的一切: pa是一个指向整数数组的指针

示例3: int(* apa [])[]

从变量名开始: apa是一个指针数组

继续到变量右侧: 数组

然后变量的左侧部分: 整数

合并我们得到的所有内容: apa是一个指向整数数组的指针数组

我希望你很清楚。

编辑:@Amarnath在上述评论中共享的链接以更详细的方式解释了相同的内容。请检查一下。