更改1D和2D可变长度数组的大小

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了更改1D和2D可变长度数组的大小相关的知识,希望对你有一定的参考价值。

通过包含可变长度数组,在C99和下一版本中,以下程序可以正常工作。

#include <stdio.h>

int main(void)

    int i, numFibs;
    printf ("How many Fibonacci numbers do you want (between 1 and 75)? ");
    scanf ("%i", &numFibs);
    if (numFibs < 1 || numFibs > 75) 
    
        printf ("Bad number, sorry!\n");
        return 1;
    
    unsigned long long int   Fibonacci[numFibs];
    Fibonacci[0] = 0;          // by definition
    Fibonacci[1] = 1;          // ditto
    for ( i = 2;  i < numFibs;  ++i )
    
        Fibonacci[i] = Fibonacci[i-2] + Fibonacci[i-1];
    
    for ( i = 0;  i < numFibs;  ++i )
    
        printf ("%llu  ", Fibonacci[i]);
        printf ("\n");
    
    return 0;

但是当我尝试实现以下程序时,它工作正常直到<= 9,任何a> 9的值,程序在数组中不会超过9个元素。

为什么?

#include <stdio.h>

int main()

    int a=0;
    int arr[a];
    printf("Enter number of rows: ");
    scanf("%d", &a);
    printf("\nNo of rows to be entered: %d\n", a);
    for(int j=0; j<a; j++)
    
        printf("Enter array element[%d]: ", j);
        scanf("%d", &arr[j]);
    
    for(int j=0; j<a; j++)
    
        printf("Entered array element [%d]: %d", j, arr[j]);
        printf("\n");
    
    return 0;

下面是一个2D数组的例子,它可以很好地工作直到b <= 2的值,该程序最终会出现分段失败。为什么?

#include <stdio.h>

int main()

    int b=0;
    int arr[b][2];
    printf("Enter number of rows: ");
    scanf("%d", &b);
    printf("No of rows to be entered: %d", b);
    for(int i=0; i<b; i++)
    
        for(int j=0; j<2; j++)
        
            printf("Enter array element[%d][%d]: ", i, j);
            scanf("%d", &arr[i][j]);
        
    
    printf("\n");
    for(int i=0; i<b; i++)
    
        for(int j=0; j<2; j++)
        
            printf("Enter array element[%d][%d]: %d", i, j, arr[i][j]);
            printf("\n");
        
    
    return 0;

在上面的示例中,动态地获取行和列将是错误的,但是动态地使用行。如果你动态地采用列,它也会失败。

有没有其他方法来解决这些问题没有malloc()?

在机器上运行的GCC版本: -

C:\ Users \ gahlot> gcc -v使用内置规范。 COLLECT_GCC = gcc COLLECT_LTO_WRAPPER = c:/ mingw / bin /../ libexec / gcc / mingw32 / 6.3.0 / lto-wrapper.exe目标:mingw32配置为:../ src / gcc-6.3.0 / configure - build = x86_64-pc-linux-gnu --host = mingw32 --target = mingw32 --with-gmp = / mingw --with-mpfr --with-mpc = / mingw --with-isl = / mingw - prefix = / mingw --disable-win32-registry --with-arch = i586 --with-tune = generic --enable-languages = c,c ++,objc,obj-c ++,fortran,ada --with-pkgversion = 'MinGW.org GCC-6.3.0-1' - enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --with-libiconv-prefix = / mingw --with-libintl-prefix = / mingw --enable-libstdcxx-debug --enable-libgomp --disable-libvtv --enable-nls线程模型:win32 gcc版本6.3。 0(MinGW.org GCC-6.3.0-1)

答案

这不符合你的想法:

int a=0;
int arr[a];
printf("Enter number of rows: ");
scanf("%d", &a);

一旦使用给定大小定义数组,即使该大小不是常量表达式,数组的大小也是固定的。大小与a的当前值无关。创建大小为0的数组也无效。

这在C标准的6.7.6.2p5节中有详细说明:

如果size是一个不是整数常量表达式的表达式:如果它出现在函数原型范围的声明中,则将其视为*被替换为*;否则,每次评估它时,其值应大于零。可变长度数组类型的每个实例的大小在其生命周期中不会改变。

在这种情况下,数组的大小由单个变量指定,但是大小可以由任何表达式确定。例如:

int f()

    int a, b, c;
    scanf("%d", &a);
    b=3;
    c=9;
    return sqrt(a) * (b - c) + sin(b);


...

int arr[f()];

如果你这样定义arr,即使你可以改变大小,你期望会发生什么?

至于为什么你的第二和第三段代码有时有效,有时却没有,这意味着你正在调用undefined behavior。在这两种情况下,这都是由创建一个至少有一个维度为0并随后尝试使用它的数组引起的。

另一答案

VLA的大小是在遇到声明时确定的。

  • 之后你不能改变它们的大小
  • size表达式的值不得为0,甚至不能为负数。

以上是关于更改1D和2D可变长度数组的大小的主要内容,如果未能解决你的问题,请参考以下文章

C99 在运行时如何计算可变长度数组的大小?

使用可变长度数组是不是有任何开销?

Numpy quirk:将函数应用于两个 1D 数组的所有对,以获得一个 2D 数组

Java实现长度可变数组

分配数组 VS。可变长度数组[重复]

在 C++ 中声明可变长度二维数组的正确方法