提问人:Jaxon Mitchell 提问时间:10/7/2023 最后编辑:ChrisJaxon Mitchell 更新时间:10/7/2023 访问量:104
C 中是否允许数组大小的变量?
Are variables in array sizes allowed in C?
问:
我在 Linux 上使用 GCC 编译器。我不明白变量在数组大小中是如何工作的。
当我运行时:
char string[6];
string[0] = 'h';
printf("%s", string);
正如预期的那样,它输出: h
如果我运行:
int x = 1;
char string[5 + x];
string[0] = 'h';
printf("%s", string);
它输出 h 后跟 和其他随机字符。我猜它正在访问内存地址,它不应该这样做。每次角色都不同,它运行。
当我做同样的事情时,但将第二行替换为“char string[5 + x] = {}” 它错误:可变大小的对象可能未初始化。
如果我对整数数组执行相同的操作,如果我键入“int array[5 + x] = {};”而不是“int array[5 + x]”,它就可以正常工作
int 数组的大小声明中是否允许变量,但 char 数组/字符串中不允许变量?
答:
如注释中所述,您的问题是以下调用了未定义的行为。
int x = 1; char string[5 + x]; string[0] = 'h'; printf("%s", string);
未定义的行为源于用作字符串。C 中的字符串需要一个 null 终止字符来表示字符串的结束。可变长度数组尚未初始化(第一个字符除外),因此内容是不确定的。您有一个相当大的内存块,但该内存可以处于任何状态。string
5 + x
在第一种情况下,显然是 ,因此以 null 终止字符串。这不能保证,正如您从第二个示例中看到的那样,其中打印了乱码,因为它在成为 null 终止符后没有看到下一个字符。string[1]
0
printf
'h'
对于静态大小的数组,我们将使用 或 将内容设置为零来初始化它,但 VLA 可能不会以这种方式初始化。{0}
{}
评论
= {};
memset()
为了解决OP关注的标题部分:
C 中是否允许数组大小的变量?
在 C99 之前:可变长度阵列 (VLA) 不是标准。
C99:标准
C11、C17:如果已定义,则不支持 VLA。
否则支持 VLA。__STDC_NO_VLA__
C23:(至少目前是这样提议的。像 C11、C17。“允许使用 VLA 类型,但创建具有自动持续时间的 VLA 对象除外......这是可选的。@tstanisl __STDC_NO_VLA__
数组的大小声明中是否允许变量,但数组/字符串中不允许变量?
int
char
如果允许一种类型,则允许所有阵列类型使用 VLA。
printf("%s", string);
是错误的代码,因为期望指向字符串的指针。 不是字符串,因为它肯定不包含 null 字符。结果:未定义的行为 (UB)。"%s"
string
评论
malloc()
static
void foo(int n) { static int (*arr)[n]; }
评论
string[1] = '\0';
char