2

我知道您不应该将具有变量的数组声明为大小 ex。int arr[n];因为如果不使用动态内存,数组的大小应该是静态的,但是如果你有这样的函数呢?这是否有效?它似乎运行得很好。它在函数内部声明的事实与它有什么关系吗?

int main() {
  int n;
  scanf("%d", &n);
  exampleFunc(n);

}

void exampleFunc(int const n) {
  int arr[n];
  for (int i = 0; i < num; i++) {
    arr[i] = i + 1;
  }
}

提前感谢您的帮助。我是 C 的菜鸟,我发现的每一个资源都适用于其他语言。

4

3 回答 3

1

GNU GCC 文档中,

ISO C99 中允许使用可变长度的自动数组。

如果您使用该std=c99标志,则可以保证它是有效代码。但是,请记住,可变长度数组 (VLA) 不是 C++ 编程的标准部分。这是 C99 标准中引入的强制性功能。

在实现尚未__STDC_NO_VLA__在 C11 支持中定义标志之前,此功能确实成为可选功能。感谢@trentcl提供了这个有效的细节。

于 2021-02-05T15:11:59.670 回答
1

对于初学者来说,for循环中有一个错字

for (int i = 0; i < num; i++) {

变量num未声明。看来你的意思

for (int i = 0; i < n; i++) {

函数声明应放在其调用之前。

用限定符 const 声明参数没有什么意义。

void exampleFunc(int const n);

这两个函数声明

void exampleFunc(int const n);

void exampleFunc(int n);

声明相同的一个函数。

这个函数内的数组声明

int arr[n];

如果您的编译器支持可变长度数组,它将是有效的。否则编译器将发出错误,数组的大小应为整数常量表达式。

可变长度数组应具有自动存储持续时间。因此,即使您的编译器支持可变长度数组,您也不能在任何函数之外声明它们,例如

const int n = 10;
int a[n];

int main( void )
{
    //...
}

此外,您可能不会在其声明中初始化可变长度数组。

这是一个使用可变长度数组的演示程序。

#include <stdio.h>

void display_pattern( size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        int a[i+1];
        
        for ( size_t j = 0; j < i + 1; j++ ) a[j] = ( i + j ) % n;
        
        for ( size_t j = 0; j < i + 1; j++ ) printf( "%d ", a[j] );
        putchar( '\n' );
    }
}

int main(void) 
{
    display_pattern( 10 );
    
    return 0;
}

程序输出为

0 
1 2 
2 3 4 
3 4 5 6 
4 5 6 7 8 
5 6 7 8 9 0 
6 7 8 9 0 1 2 
7 8 9 0 1 2 3 4 
8 9 0 1 2 3 4 5 6 
9 0 1 2 3 4 5 6 7 8 
于 2021-02-05T15:52:21.713 回答
0

该语言的 1999 修订版引入了可变长度数组,其中数组维度可以用运行时变量而不是编译时常量1来指定。它们涵盖exampleFunc您的.malloc

VLA 的使用受到限制 - 它们不能用作全局变量或声明为static,您不能在它们的声明中使用初始化器,并且它们不能任意大。

VLA 支持在 C99 后的实现中参差不齐,2011 年的修订版使其支持成为可选。为了完全安全,您应该检查语言版本和__STDC_NO_VLA__宏以确定您的实现是否支持它们2

void exampleFunc( const int n )
{
#if __STDC_VERSION__ >= 199901L && !defined(__STDC_NO_VLA__) 
  int arr[n];
#else
  int *arr = malloc( sizeof *arr * n );
#endif

// do stuff with arr

#if !(__STDC_VERSION__ >= 19901L && !defined(__STDC_NO_VLA__))
  free( arr );
#endif
}

  1. 尽管有这个名字,可变长度数组的大小对于任何给定的定义都是固定的;定义后无法调整大小。
  2. 就个人而言,我会反转该功能宏的含义,重命名它__STDC_VLA__并仅在支持 VLA定义它,但我不是标准委员会的成员。
于 2021-02-05T16:53:15.703 回答