struct grid {
int width, height;
void *cells[];
};
typedef struct grid grid;
int main(){
enum { width = 2, height = 10 };
grid *g = malloc(sizeof(grid) + width * height * sizeof(void *));
void *(*cells)[10] = &g->cells;
}
我的教授告诉我们这种分配灵活数组然后分配指向整个指针数组的指针的好方法
void *(*cells)[10] = &g->cells;
< - 此行
所以我尝试了这种方法
char *array[10];
char *(*pointer)[2] = &array;
它只是给了我一个编译错误
warning: incompatible pointer types initializing
'char *(*)[2]' with an expression of type 'char *(*)[10]'
[-Wincompatible-pointer-types]
char *(*pointer)[2] = &array;
如果有人能向我解释“指向整个数组的指针”的功能 这将是有用的。谢谢
答案 0 :(得分:3)
让我们先做出正确的声明:
void *(*cells)[10] = &g->cells;
要理解这一点,首先要认识到cells
是要声明的标识符,并从那里遵循优先规则:
(*cells)
表示cells
是一个指针,声明的其余部分描述了指向的东西。括号只是强制执行优先级,就像在算术表达式中一样。[10]
适用于下一个,因为括号的优先级高于一元*
。这就是说,(*cells)
是一个包含10个元素的数组。void *
保留在前面,这将给出每个元素的类型。如果我们查看&g->cells
,它就是指向未指定数量void *
的数组的指针。
现在考虑一下你的代码:
char *array[10]; char *(*pointer)[2] = &array;
遵循类似的过程,我们得到pointer
被声明为指向2 char *
数组的指针。到现在为止还挺好。现在,您要分配给它的是什么?为什么,它是指向 10 char *
数组的指针。这是指向不同的,不兼容类型的指针。
在第一种情况下,初始化程序的类型是指向“不完整类型”的指针,该指针与指针指向的类型兼容。 (它是不完整的,因为数组长度未指定;它是兼容的,因为在所有其他方面它与另一种类型匹配。)指向的东西可以是由赋值隐式声明的长度的数组,C将把指针看作是它。
在第二种情况下,C可以看到两个指针肯定指向不同大小的对象,因此赋值肯定是不正确的。您需要对pointer
的类型进行强制转换或更改才能使其接受初始化。
答案 1 :(得分:2)
&array
是包含10个指向char
pointer
是一个指向包含2个指向char
2 != 10
,
因此警告。
有一个方便的website有助于理解困难的c减速。