我宣布一个变量' ptr'像这样:
int array[4][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
int n = 4;
int (*ptr)[n] = (int (*)[n])array[0];
当把它放在全局时,我在编译程序时遇到错误:
error: variably modified ‘ptr’ at file scope
int (*ptr)[n] = (int (*)[n])array[0];
^
但是当我把它放在本地时它会成功。
btw:我使用的是gcc编译器。
答案 0 :(得分:3)
带有可变修改类型的变量仅允许在块范围(即在函数内)。
可变修改类型表示一种数组类型,其中一个维度在编译时未知,或者任何类型派生(例如指向此类数组的指针) ,如你的例子)。
int (*ptr)[n]
具有不同的修改类型,因为n
不是常量表达式。由于历史原因,const int n = 4;
也不会算作常量表达式。但是#define n 4
将是一个不变的表达式。
一种解决方法是写:
int (*ptr)[ sizeof array / sizeof array[0] ] = &array[0]; // note: no cast required
背景:在C99中添加了可变修改类型,以支持直到运行时才知道其维度的数组。
虽然由于堆栈溢出实际上使用这样的数组是有风险的,但是这种语法可以产生一些很好的后续效果。例如,use array syntax with malloc'd arrays的能力,以及具有可以使用数组语法在多维数组上操作的函数的能力;但接受各种大小的阵列。
关于为什么在文件范围内不允许这些原因的理由see the answers to this question。 (目前该问题被错误地关闭为重复,但答案很好)