【问题标题】:What's the difference between global variables and local variables, when declare a pointer to array?声明指向数组的指针时,全局变量和局部变量有什么区别?
【发布时间】:2014-11-24 14:08:57
【问题描述】:

我这样声明一个变量“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];
       ^

但它会成功,当我把它放在本地时。

顺便说一句:我使用 gcc 编译器。

【问题讨论】:

    标签: c arrays gcc


    【解决方案1】:

    可变修改类型的变量只允许在块范围(即在函数内部)。

    可变修改类型是指一种数组类型,其中一个维度在编译时是未知的,或任何类型派生(例如指向此类数组的指针) ,就像你的例子一样)。

    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。 (目前该问题被错误地关闭为重复,但答案很好)

    【讨论】:

    • n 的值也可以如下计算,对吗? #define n (sizeof(array)/sizeof(array[0])) int (*ptr)[n] = &array[0]
    • 是的,#define 只是一个文本替换。
    • 其实我只是在函数中使用它,比如这个void fun(int array[], int n)。但是我真的不明白它是怎么工作的?为什么我可以声明一个变量具有可变修改类型?:)
    • 函数参数列表中没有数组; int array[] is actually a pointer 穿着羊皮。
    • 是的。但是我真的很想知道为什么我不能在全球范围内使用它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 2021-11-11
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多