据我所知,在 c 语言中,数组在编译时需要有一个特定的大小。
但是我不明白为什么这段代码仍然可以工作?
int s;
printf("enter the array size: ");
scanf("%d",&s);
int a[s]; // Isn't s value determined at run time?
据我所知,在 c 语言中,数组在编译时需要有一个特定的大小。
但是我不明白为什么这段代码仍然可以工作?
int s;
printf("enter the array size: ");
scanf("%d",&s);
int a[s]; // Isn't s value determined at run time?
在 ANSI 89 C 中,需要知道数组的大小。而规范的 99 版本取消了这个限制,并允许使用可变大小的数组。
下面是该功能的 GNU 版本文档:
可变长度数组自C99以来就是C语言的一部分。 但在C11中它们被作为可选功能 - 这意味着符合C11的实现不需要提供它(尽管,实际上支持C99的所有实现都肯定在C11中提供VLAs)。
您可以使用宏__STDC_NO_VLA__
来检查您的实现是否不支持VLAs(如果在C99或C11编译模式下定义,则您的实现不支持VLAs)。
因此,在现代C(>= C99)中可以在运行时决定数组大小,像下面这样的代码是可以的:
int s;
printf("Enter the array size: ");
scanf("%d", &s);
int a[s];
alloca()
,它类似于VLA,并具有与VLAs相同的缺点)。int s;
printf("enter the array size: ");
scanf("%d",&s);
int *a = malloc(s * sizeof *a);
...
free(a);
int *a = malloc(sizeof(int) * s)
(int*)
的强制类型转换,如果你忘记包含定义malloc
的文件,编译器将会生成一个错误。因此最好的做法是不要包含这个强制类型转换。 - Mark Ransomint *a = malloc(s * sizeof *a)
- AnT stands with Russia这段代码是符合C99语言规范的。同时,作为扩展功能,GCC编译器也支持在C89/90模式下编译该代码。
因此,对于你的问题(为什么它“能用”),答案取决于你如何进行编译。一般情况下,这段代码甚至无法被C89/90编译器编译。
sizeof()
除以总数,再除以一个元素的大小(比如第一个元素)。 sizeof(a)/sizeof(a[0])
2) 根据您的问题动态分配内存:
int *a = (int*)malloc( s * sizeof(int) );
了解编译器如何分配变量的内存是回答您问题的关键。变量的内存分配有两种模式,可以在堆上分配,也可以在栈上分配。堆上的内存是动态分配的。因此,在堆上分配内存的变量可以在运行时给出其大小。
C语言中的数组在栈上分配内存。为了在栈上提供内存,编译器在编译时应该知道内存的大小。这样,在运行时就可以为变量在栈上设置足够的内存。这就是为什么在C语言中不能在运行时决定数组的大小的原因。
alloca()
在此之前多年就提供了相同的功能。 - caf