我正在分析一些多线程代码。在初始化函数中,有一段代码如下:
for(i=0;i<MAX_STREAMS;i++){
cmdStreamTaskPtr[i] = NULL;
}
我理解语法,但我的问题出在cmdStreamTaskPtr
的声明中。它的定义方式如下:cmdData_t
为typedef struct
且MAX_STREAMS
为5。
static cmdData_t *(*cmdStreamTaskPtr[MAX_STREAMS])(void) = {[0 ... MAX_STREAMS-1] = NULL};
我不知道这条线是什么意思。它是一个具有默认值的变量吗?
答案 0 :(得分:25)
cmdStreamTaskPtr
是一个数组:
cmdStreamTaskPtr[MAX_STREAMS]
指针:
*cmdStreamTaskPtr[MAX_STREAMS]
对于不接受任何参数的函数:
(*cmdStreamTaskPtr[MAX_STREAMS])(void)
并返回cmdData_t *
:
cmdData_t *(*cmdStreamTaskPtr[MAX_STREAMS])(void)
并且是static
:
static cmdData_t *(*cmdStreamTaskPtr[MAX_STREAMS])(void)
然后使用NULL
为所有数组成员初始化该数组:
static cmdData_t *(*cmdStreamTaskPtr[MAX_STREAMS])(void) = {[0 ... MAX_STREAMS-1] = NULL};
请注意,初始化语法[0 ... MAX_STREAMS-1]
不是标准C,而是GCC支持的扩展名。在这种情况下它也是多余的,因为数组被声明为static
,这意味着它具有静态存储持续时间,因此如果没有显式初始化,它的元素将被隐式初始化为NULL
。
使用typedef
可以更清楚地使用函数指针。在这种情况下,我们可以创建以下typedef:
typedef cmdData_t *(*fp)(void);
这使fp
成为指向函数指针的typedef,该函数不带参数并返回cmdData_t *
。然后可以将数组定义更改为:
static fp cmdStreamTaskPtr[MAX_STREAMS];
所以现在应该更清楚cmdStreamTaskPtr
是fp
的数组,其中fp
是先前定义的函数指针。
答案 1 :(得分:-2)
cmdStreamTaskPtr
是一个指向函数的指针数组,这些函数不带参数并返回指向cmdData_t
的指针。您可以通过阅读声明作为用法来说明:cmdStreamTaskPtr
首先是下标,因为下标的优先级高于解除引用,然后结果被取消引用,然后结果在void(无)上调用,如果结果是函数调用被解除引用后我们最终获得cmdData_t
。 static
存储持续时间说明符适用于数组,并且是冗余的,因为默认情况下全局变量是静态的。此外,代码{[0 ... MAX_STREAMS - 1]= NULL}
使用范围指定的初始化程序,它是C语言的gnu扩展,将所有内容设置为null,这有三个原因是多余的:初始化程序列表的未指定元素自动设置为零,静态存储变量自动设置为零,稍后会有代码将数组设置为零。