2016-08-30 88 views
1

我是C语言编程中的新手。有人可以向我解释如何“读取”*(float*)a等声明并逐步给出一些示例。读取C指针类型声明

谢谢!

+4

这不是一个声明。它将一个变量'a'解引用到指向'float'的指针。 –

+0

@EugeneSh。请详细解释一下!谢谢:) –

+0

[C++中指针变量和引用变量之间的区别是什么?](可能是C++中的指针变量和引用变量之间的区别是什么?)(http://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer -variable-and-a-reference-variable-in) – RCB

回答

1

在一般情况下,你必须关心的优先级都与操作符的结合:table

在这种情况下,解引用和转换运算符具有相同的优先级,都是从右到左associatives。这意味着每个运算符都适用于其右侧的内容,并且由于它们具有相同的优先级,所以取消引用运算符将​​应用于右侧的投射运算符之后。

所以执行的操作顺序是:访问一个 - >将其转换为(float *) - >解引用它。

编辑:在你有一元运算符(取消引用,转换,否定等)的情况下,该运算符总是从右到左联合,并且在计算右侧的所有表达式后应用。因此,在我们的案例中,您可以说操作员从右向左应用,而不必查看上表。

+1

我不确定优先级与此处有关 - 左侧的'*'可应用于(语法上)的** only **是'(float *)a'的结果。 –

+0

谢谢! @Davide Visentin –

+0

'(int *) - >(float *)'也许。 – sjsam

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。请注意,在功能声明中,不必指定参数名称。他们需要在相应的功能定义中指定。

+0

什么是例如:(float *)xfunction(x,y,z)? @John Bode –

+0

@M_sansa - 它是一个函数*调用*,并将返回值转换为指向'float'的指针。 –