读取C指针类型声明

时间:2016-08-30 18:27:59

标签: c pointers types

我是C语言编程的新手。有人可以解释我如何阅读"像*(float*)a这样的声明,并逐步给出一些例子。

谢谢!

2 个答案:

答案 0 :(得分:0)

通常,您必须关注运算符的优先级和关联性:table

在这种情况下,取消引用和强制转换操作符具有相同的优先级,并且都是从右到左的关联。这意味着每个运算符都应用于其右侧的内容,并且由于它们具有相同的优先级,因此取消引用运算符应用于右侧的强制转换运算符。

所以执行的操作顺序是:访问a - >把它投到(浮动*) - >取消引用它。

编辑:如果您有一元运算符(取消引用,强制转换,否定等),该运算符始终是从右到左的关联,并且在计算出右侧的所有表达式后应用它。因此,在我们的例子中,您可以说操作符从右到左也适用,而无需查看上表。

答案 1 :(得分:0)

*(float *)a不是声明;它是强制转换表达式。在这种特殊情况下,它采用a的值,将其视为指向float的指针,并取消引用结果。最有可能a是指向不同类型的指针,我们希望将其视为指向float的指针。

就指针声明而言......

简单的指针声明看起来像

T *p;  // p is a pointer to T

其中T是任何类型(可能包含constvolatile等限定符。 对象 p的类型是“指向T的指针”;该类型由T声明符 *p中的类型说明符和限定符的组合完全指定。

声明符引入了声明的事物的名称,以及类型说明符中未提供的任何类型信息。在上面的声明中*p是声明者。它提供对象的名称(p)和任何其他类型信息(指向)。请注意,即使您将声明写为

T* p;

解析

T (*p);

对于数组和函数的声明也是如此:

T a[N]; // a is an N-element array of T
T f();  // f is a function returning T

a的数组由声明符a[N]提供,f的函数由声明符f()给出。

您可以将*[]()结合使用,如下所示:

T *a[N];   // a is an N-element of pointers to T
T (*a)[N]; // a is a pointer to an N-element array of T
T *f();    // f is a function returning pointer to T
T (*f)();  // f is a pointer to a function returning T

在声明和表达式中,一元*的优先级低于后缀[](),因此*a[N]*f()解析*(a[N])*(f())。如果您希望a成为指向数组而不是指针数组的指针,则必须将*a明确地分组为(*a)[N]

您可以进一步组合这些元素:

T **p;       // p is a pointer to a pointer to T
T a[N][M];   // a is an NxM array of T
T (*f[N])(); // f is an array of pointers to functions returning T
T (*f())[N]; // f is a function returning a pointer to an array of T
T *(*(*a[N])())(); // a is an array of pointers to functions returning pointers to functions returning pointers to T

是的,函数可以返回指向数组的指针和指向其他函数的指针,是的,语法看起来很时髦,但是如果逻辑上遵循声明器的工作方式。您只需将函数调用(以及任何参数)替换为指针名称:

T (*a)[N] => T (*f())[N], a => f()
T (*f)()  => T (*g())(),  f => g()

以下是一个示例:C标准库中的signal函数。它是一个返回指向另一个函数的指针的函数:

void (*signal(int sig, void (*func)(int)))(int);

要阅读此声明,请从最左边的标识符开始,然后按照上面给出的优先规则逐步解决。递归地将这些规则应用于任何函数参数:

       signal                                      -- signal
       signal(                          )          -- is a function taking
       signal(    sig                   )          --   parameter sig
       signal(int sig                   )          --   is an int
       signal(int sig,        func      )          --   parameter func
       signal(int sig,      (*func)     )          --   is a pointer
       signal(int sig,      (*func)(   ))          --   to a function taking
       signal(int sig,      (*func)(   ))          --     unnamed parameter
       signal(int sig,      (*func)(int))          --     is an int
       signal(int sig, void (*func)(int))          --   returning void
      *signal(int sig, void (*func)(int))          -- returning a pointer
     (*signal(int sig, void (*func)(int)))(   )    -- to a function taking
     (*signal(int sig, void (*func)(int)))(   )    --   unnamed parameter
     (*signal(int sig, void (*func)(int)))(int)    --   is an int  
void (*signal(int sig, void (*func)(int)))(int);   -- returning void

因此,signal是一个返回指向函数的指针的函数。 signal有两个参数,一个是普通的int,另一个是指向一个函数的指针,它接受int并返回void。请注意,在函数声明中,不必指定参数名称。它们需要在相应的函数定义中指定。