数组的大小可以在c中运行时确定吗?

发布于 2024-08-09 12:54:13 字数 196 浏览 6 评论 0原文

据我所知,在c中编译之前,数组需要具有特定的大小。

我想知道为什么这段代码仍然有效?

int s;
printf("enter the array size: ");
scanf("%d",&s);

int a[s]; // Isn't s value determined at run time?

As I know, an array needs to have a specific size before compiling time in c.

I wonder why this code still works?

int s;
printf("enter the array size: ");
scanf("%d",&s);

int a[s]; // Isn't s value determined at run time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

回梦 2024-08-16 12:54:13

需要使用 ANSI 89 C 了解数组大小。该规范的 99 版本删除了此限制并允许使用可变大小的数组。

这是此功能的 GNU 版本的文档

Array sizes need to be known with ANSI 89 C. The 99 version of the spec removed this limitation and allowed for variable sized arrays.

Here is the documentation no the GNU version of this feature

时常饿 2024-08-16 12:54:13

可变长度数组自从C99
但它们已在 C11 中作为可选功能 - 意味着需要符合 C11 的实现不提供它(尽管实际上所有支持 C99 的实现都肯定在 C11 中提供了 VLA)。

您可以使用宏 检查您的实现是否不提供 VLA __STDC_NO_VLA__(如果它是在 C99 或 C11 编译模式中定义的,则您的实现不支持 VLA)。

因此,在现代 C (>= C99) 中可以在运行时决定数组大小,并且像下面这样的代码就可以了:

int s;
printf("Enter the array size: ");
scanf("%d", &s);
int a[s];

VLA 的一个明显缺点是,如果 s 相当大并且 s 的分配code>a 可能会失败。更糟糕的是,没有办法检查分配是否失败,并且您将遇到运行时错误(例如,段错误)。它本质上是未定义行为。因此,如果数组大小太大,您希望避免使用 VLA。基本上,当有疑问时,请进行动态内存分配(见下文)。

VLA 的另一个问题(与其他问题相比不太严重)是它们具有自动存储持续时间(也称为“堆栈分配”)。因此,如果您想要比声明 VLA 的块作用域持续时间更长的内容,那么 VLA 没有任何帮助。

同样相关的是,C89 中没有 VLA。所以使用动态内存分配是唯一的方法。虽然,有一些非标准扩展,例如 alloca() 与 VLA 类似,并且具有与 VLA 相同的缺点)。

int s;
printf("enter the array size: ");
scanf("%d",&s);
int *a = malloc(s * sizeof *a);
...
free(a);

Variable Length Arrays have been part of C language since C99.
But they have been made as an optional feature in C11 - meaning a C11 conforming implementation need not provide it (although, practically all the implementation that support C99 certainly provide VLAs in C11).

You can check if you implementation does not provide VLAs using the macro __STDC_NO_VLA__ (If it's defined in C99 or C11 mode of compilation, then your implementation doesn't support VLAs).

So deciding an array size at runtime is possible in modern C (>= C99) and code like the below is fine:

int s;
printf("Enter the array size: ");
scanf("%d", &s);
int a[s];

One obvious drawback of VLAs is that if s is quite big and the allocation of a could fail. Worse, there's no way to check if the allocation has failed and you'll run into runtime errors (e.g., segfault). It's essentially undefined behaviour. So you want to avoid VLAs if the array size is too big. Basically, when in doubt, go for dynamic memory allocation (see below).

Another issue, much less severe compared to other, with VLAs is that they have automatic storage duration (aka "stack allocated"). So if you want something that lasts for longer duration then the block scope where the VLA is declared, then VLAs are of no help.

Also relevant is that there's no VLA in C89,. So using the dynamic memory allocation is the only way. Although, there were some non-standard extensions such as alloca() which is similar to VLA and has the same drawbacks as VLAs).

int s;
printf("enter the array size: ");
scanf("%d",&s);
int *a = malloc(s * sizeof *a);
...
free(a);
做个ˇ局外人 2024-08-16 12:54:13

如果需要分配动态大小的数组,则必须使用 malloc() 从堆中获取它。

int *a = malloc(sizeof(int) * s)

If you need to allocate an array with dynamic size, you have to get it from the heap, with malloc().

int *a = malloc(sizeof(int) * s)
对岸观火 2024-08-16 12:54:13

此代码受 C99 语言规范支持。 C89/90 模式下的 GCC 编译器也支持此代码作为扩展。

因此,您的问题的答案(为什么它“有效”)取决于您如何编译它。一般情况下,C89/90 编译器甚至无法编译它。

This code is supported by C99 language specification. This code is also supported by GCC compiler in C89/90 mode as an extension.

So, the answer to your question (why it "works") depends on how you are compiling it. In general case, this will not even compile by a C89/90 compiler.

打小就很酷 2024-08-16 12:54:13

您在这里混淆了两件事。

1)确定已分配数组的大小(正如您的标题所暗示的):将总数除以一个(例如第一个)元素的大小:

 sizeof(a)/sizeof(a[0])

2)动态分配内存为你的问题是:

 int *a = (int*)malloc( s * sizeof(int) );

You are confusing two things here.

1) Determining the size of an already allocated array (which your title implies): divide sizeof() for the total by the size of one (say, the first) element:

 sizeof(a)/sizeof(a[0])

2) Dynamically allocating memory as your question asks:

 int *a = (int*)malloc( s * sizeof(int) );
桜花祭 2024-08-16 12:54:13

了解编译器如何将内存分配给变量以正确回答您的问题非常重要。内存分配给变量有两种模式,它可以在堆上,也可以在堆栈上。堆上的内存是动态分配的。因此,在堆上分配内存的变量可以在运行时指定其大小。

C 语言中的数组被赋予堆栈上的内存。为了在堆栈上提供内存,编译器在编译时应该知道内存的大小。这样在运行时就可以为堆栈上的变量留出足够的内存。这就是 C 语言无法在运行时决定数组大小的原因。

Its important to understand how memory is allocated to variable by a compiler to give proper answer to your question. There are two modes in which memory is allocated to variable, it can be on a heap or it can be on a stack. Memory on a heap is allocated dynamically. So a variable that is allocated memory on a heap can be given its size during run time.

The arrays in case of C are given memory on a stack. For providing memory on a stack the size of the memory should be known to the compiler during compile time. So that during run time that much memory can be set aside for the variable on the stack. That is the reason you cannot decide the size of the array at run time as far as C language is concerned.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文