为什么具有可变大小的数组可以工作而不是动态数组?

问题描述

首先,我是编程新手,不知道“可变大小数组”和“动态数组”是什么意思。 我只是用这些词来描述我的情况。随意使用正确的命名法进行编辑。 现在的问题,我有以下几段代码:-

div[id^="val"]

...
int n;
printf("Enter number of rows/columns = ");
scanf(" %d",n);
int a[n][n];
...

两个都编译成功。

  • 在第一种情况下,程序在执行 ... int n; n=6; int a[n][n]; ... n=7; ... n=4; ... 函数后崩溃。
  • 第二种情况完美运行。

为什么?

解决方法

&中使用scanf()

当您使用 scanf 中的 <stdio.h> 扫描用户输入时,您需要传递一个指向它的指针。您可以在此处详细了解为什么会出现这种情况:Use of & in scanf() but not in printf()

int n;
printf("Integer: ");
scanf("%d",&n);
int a[n][n];

变长数组

variable-length array 只是一个数组,其长度在运行时而不是在编译时确定。在您的情况下,长度由变量 n 决定,这使其成为可变长度数组。正如注释中提到的 Eugene Sh. 一样,更改变量 n 不会在定义数组后修改数组的长度。

,

在两个代码片段中都使用了可变长度数组,因为在它们的声明中没有使用指定数组中元素数量的整数常量表达式。

没有动态分配的数组。

第一个代码片段在调用 scanf 的语句中有一个错误。

scanf(" %d",n);

参数应该是一个指向变量 n 的指针。

scanf(" %d",&n);

就是通过函数n来改变变量scanf,你必须通过引用将它传递给函数。

在 C 中,通过引用传递意味着通过指向对象的指针间接传递对象。因此,取消引用该指针的函数将可以直接访问必须修改的对象。

注意在第二个代码片段中,在数组声明之后改变变量 n 的值不会改变数组 a 中的元素数量。

int n;
n=6;
int a[n][n];
...
n=7;
...
n=4;

根据数组声明之前存储在变量 a 中的值,数组 6 将正好有 n 个元素。

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    size_t n;
    
    do
    {
        printf( "Enter number of rows/columns (greater than 0 ) = " );
        
    } while ( !( scanf( "%zu",&n ) == 1 && n != 0 ) );
    
    int a[n][n];
    
    printf( "The size of the array declared like int a[%zu][%zu] is %zu.\n",n,sizeof( a ) );
    
    return 0;
}

程序输出可能看起来像

Enter number of rows/columns (greater than 0 ) = 10
The size of the array declared like int a[10][10] is 400.

可变长度数组应具有自动存储持续时间(也就是说,它不能在例如文件范围内声明或具有存储说明符 static;它可以在块范围内声明)。

来自 C 标准(6.7.6.2 数组声明符)

4 如果大小不存在,则数组类型为不完整类型。如果 大小是 * 而不是表达式,数组类型是 未指定大小的变长数组类型,只能使用 在具有函数原型作用域的声明或类型名称中;这样的 数组仍然是完整的类型。 如果大小是整数 常量表达式并且元素类型具有已知的常量大小, 数组类型不是变长数组类型;否则, 数组类型是变长数组类型。(变长数组 是实现不需要支持的条件特性;看 6.10.8.3.)