这是在 C 中声明数组的有效方法吗?

问题描述

我知道你不应该用一个变量作为大小 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 的菜鸟,我找到的所有资源都适用于其他语言。

解决方法

来自GNU GCC documentation

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

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

在 C11 支持中未定义 __STDC_NO_VLA__ 标志之前,此功能已成为可选。 Thanks to @trentcl 这个有效的细节。

,

对于初学者来说,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 
,

该语言的 1999 年修订版引入了变长数组,其中可以使用运行时变量而不是编译时常量指定数组维度1。它们涵盖了您的 exampleFunc 中的确切用例,允许您声明一个直到运行时才知道其大小的本地数组而不必依赖于 malloc

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

在 C99 之后的实现中,VLA 支持参差不齐,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 时才定义它,但我不符合标准委员会。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...