在C语言中,使用const变量来定义数组的大小。

7

我发现了一个有趣的事实,但是我不明白它是如何工作的。

以下这段代码完美地运行。

#include <stdio.h>

int main() {
  const int size = 10;
  int sampleArray[size];
  typedef char String [size];
  return 0;
}

然后,我尝试只使用具有全局范围的常量变量,而且仍然正常。

#include <stdio.h>

const int size = 10;

int main() {
  int sampleArray[size];
  typedef char String [size];
  return 0;
}

但是,如果我将数组的作用域也改为全局的话,我会得到以下错误信息:
错误:文件作用域下的可变大小的‘sampleArray’
#include <stdio.h>

const int size = 10;
int sampleArray[size];

typedef char String [size];

int main() {
  return 0;
}

我没明白!如果我把常量变量替换成#define,也可以。我知道#define变量是预处理的,而且据我所知,常量变量只是只读的。但到底是什么导致了全局作用域的问题呢?
我不明白第三段代码有什么问题,如果第二段代码是正常的话。

3
一些细节:C语言中有“const”对象,但没有真正的常量对象。尽管“const”似乎意味着常量,但“const”对象不是真正的常量,更像是“这个对象不应该改变,但是如果试图进行更改-谁知道会发生什么?”在C语言中,真正的常量是像“42”这样的代码,它是一个带有“int”类型的“整数常量”。因此,“const int size = 10;”不是一个常量变量。 - chux - Reinstate Monica
该数组没有固定的大小,而是一个可变长度的数组。 - too honest for this site
1
就像他们所说的,C语言有“const”对象,实际上是只读“变量”。相较于拥有真正意义的编译时常数的C++,其具备真正的“const”对象。 - David R Tribble
1
一个 const 变量是编译器不允许修改的变量,但它仍然是一个变量。虽然该值可能在编译时未知(因为它可能来自其他文件),但数组大小必须是已知的,因此被禁止修改。 - Luis Colorado
替代副本:*C中的文件范围内可变修改的数组*。 - Peter Mortensen
1个回答

7
可变长度数组(VLAs)只能具有自动存储期。VLAs是在C99中引入的。
不允许使用静态存储期声明VLA,因为VLA的大小是在运行时确定的(见下文)。
在此标准之前,您可以使用类似于宏的方式
#define SIZE 10

//...

int a[SIZE];

或者一个枚举的枚举器

enum { SIZE = 10; }

//...

int a[SIZE];

顺便说一下,你可以移除const限定符,直接写。
int size = 10;

替代

const int size = 10;

在C++中,你必须使用const限定符。在C++中,除了一些编译器可能有自己的语言扩展之外,没有任何可变长度数组(VLAs)。
请注意,对于可变长度数组,sizeof运算符是在运行时而不是编译时计算的。

谢谢,我刚开始理解得更多了!但是,如果我不用const尝试,我会得到相同的全局作用域错误。但是使用#define SIZE 10,它可以正常工作。 - Bálint Pap
@BálintPap 正如我所写的,可变长数组可能没有所有全局数组都具有的静态存储期。 - Vlad from Moscow
好的,我们开始吧!嗯,从来没有考虑过那个问题。谢谢你的解释!我真的很感激! - Bálint Pap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接