读取C指针类型声明
我是C语言编程新手。有人能给我解释一下如何“阅读”像读取C指针类型声明,c,pointers,types,C,Pointers,Types,我是C语言编程新手。有人能给我解释一下如何“阅读”像*(float*)a这样的声明,并一步一步地给出一些例子吗 谢谢 通常,您必须同时考虑运算符的优先级和关联性: 在这种情况下,取消引用操作符和强制转换操作符具有相同的优先级,并且都是从右到左的关联。这意味着每个操作符应用于其右侧的内容,并且由于它们具有相同的优先级,因此解引用操作符在其右侧的强制转换操作符之后应用 因此,执行的操作顺序是:访问->将其转换为(float*)->取消引用它 编辑:如果有一元运算符(取消引用、强制转换、求反等),则该
*(float*)a这样的声明,并一步一步地给出一些例子吗
谢谢 通常,您必须同时考虑运算符的优先级和关联性:
在这种情况下,取消引用操作符和强制转换操作符具有相同的优先级,并且都是从右到左的关联。这意味着每个操作符应用于其右侧的内容,并且由于它们具有相同的优先级,因此解引用操作符在其右侧的强制转换操作符之后应用
因此,执行的操作顺序是:访问->将其转换为(float*)->取消引用它
编辑:如果有一元运算符(取消引用、强制转换、求反等),则该运算符始终是从右向左关联的,并且在计算其右侧的所有表达式后应用。因此,在我们的例子中,您可以说运算符也是从右向左应用的,而无需查看上表。*(float*)a
不是声明;这是一个演员的表情。在这种特殊情况下,它取a
的值,将其视为指向float
的指针,并取消对结果的引用。很可能a
是指向不同类型的指针,我们希望将其视为指向float
的指针
就指针声明而言
一个简单的指针声明如下所示
T *p; // p is a pointer to T
其中,T
是任何类型(可能带有限定符,如const
或volatile
)。对象p
的类型是“指向T
”的指针;类型完全由T
中的类型说明符和限定符以及声明符*p
组合指定
声明器引入被声明对象的名称,以及类型说明符中未提供的任何类型信息。在上面的声明中,*p
是声明者。它提供对象的名称(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标准库中的信号
函数。它是一个返回指向另一个函数的指针的函数:
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的函数的指针。注意,在函数声明中,不必指定参数名。它们需要在相应的函数定义中指定 这不是一个声明。它将取消引用一个变量a
强制转换为指向float
@EugeneSh的指针。请多解释!谢谢:)假设您正在编写qsort
所需的cmp
函数,该函数有两个void*
参数,则该函数可能重复。您知道它们实际上指向float
所以如果(*(float*)a>*(float*)b)返回1代码>用于铸造正确的数据类型.@ RCB——这是关于C++的。我不确定这里的优先级是相关的。左边的代码> */C>可以应用到(语法上)是<代码>(浮点*)< < /代码>的结果。谢谢!戴维德·维森丁(int*)->(float*)
也许吧。@OliverCharlesworth你是对的。无论如何,这是一个通用的算法,可以用来理解任何表达式。无论如何,我在答案中加了一个注释。Thanks@sjsam是的,现在我已经修好了。谢谢。例如:(float*)xfunction(x,y,z)是什么@约翰Bode@M_sansa-这是一个函数调用,返回值被转换为指向float
的指针。
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