Cprogramming 简明教程

Variable Length Arrays in C

C 中的可变长度数组也称为可变大小或运行时大小数组。它是一个其长度是在运行时而不是在编译程序时确定的数组。其大小取决于在程序的运行时生成的数值,通常作为来自用户的输入接收。

通常,数组大小在程序中预先声明如下所示 −

int arr[10];

数组的大小一旦声明,将在程序执行期间保持不变,并且在其运行时不能改变。但是,对于可变长度数组 (VLA),编译器会在堆栈上分配具有自动存储持续时间的内存。在 C99 标准中添加了对 VLA 的支持。

Creating a Variable Length Array

用于创建可变长度数组的 syntax 如下 −

void arr_init(int length){

   int arr[length];

   //code using arr;

};

Example

以下示例演示了如何创建一个可变长度数组 −

#include <stdio.h>

int main(){

   int i, j;
   int size; // variable to hold size of one-dimensional array

   printf("Enter the size of one-dimensional array: ");
   scanf("%d", &size);

   int arr[size];

   for(i = 0; i < size; ++i){
      printf("Enter a number: ");
      scanf("%d", &j);
      arr[i] = j;
   }

   for(i = 0; i < size; ++i)
   printf("a[%d]: %d\n", i, arr[i]);

   return 0;
}

当运行此代码时,它将要求您输入数组的大小。请注意,数组的长度在声明时未被固定。您在运行时定义其大小。

Enter the size of one-dimensional array: 5
Enter a number: 1
Enter a number: 5
Enter a number: 7
Enter a number: 8
Enter a number: 7

a[0]: 1
a[1]: 5
a[2]: 7
a[3]: 8
a[4]: 7

Two-dimensional Variable Length Arrays

我们还可以声明并使用二维可变长度数组。

Example 1

请看以下示例:

#include <stdio.h>

int main(){

   int i, j, x;

   int row, col; // number of rows & columns of two D array

   printf("Enter number of rows & columns of 2-D array:\n");
   scanf("%d %d", &row, &col);

   int arr2D[row][col];
   for(i = 0; i < row; ++i){
      for(j = 0; j < col; ++j){
         printf("Enter a number: ");
         scanf("%d", &x);
         arr2D[i][j] = x;
      }
   }

   for(i = 0; i < row; ++i){
      printf("\n");
      for(j = 0; j < col; ++j)
         printf("%d\t", arr2D[i][j]);
   }

   return 0;
}

运行代码并检查其输出:

Enter number of rows & columns of 2-D array:
2
3
Enter a number: 10
Enter a number: 20
Enter a number: 30
Enter a number: 40
Enter a number: 50
Enter a number: 60
10	20	30
40	50	60

Example 2

以下代码声明一个可变长度的一维数组,并用累加的数字填充它:

#include <stdio.h>

int main(){

   int n;

   printf("Enter the size of the array: \n");
   scanf("%d", &n);

   int arr[n];

   for(int i = 0; i < n; i++)
      arr[i] = i+1;

   printf("The array elements are: ");

   for(int i = 0; i < n; i++)
      printf("%d ", arr[i]);

   return 0;
}

运行代码并检查其输出:

Enter the size of the array:
5
The array elements are: 1 2 3 4 5 ....

Example 3

以下代码使用标头文件 stdlib.h 中的函数 srand()rand() ,用随机生成的数字填充可变长度的数组。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void oneDArray(int length, int a[length]);

// function prototype
void twoDArray(int row, int col, int a[row][col]);

// function prototype
int main(){

   int i, j;

   // counter variable
   int size;

   // variable to hold size of one dimensional array
   int row, col;

   // number of rows & columns of two D array
   srand(time(NULL));

   printf("Enter the size of one-dimensional array: ");
   scanf("%d", &size);

   printf("Enter the number of rows & columns of 2-D array:\n");
   scanf("%d %d", &row, &col);

   // declaring arrays
   int arr[size];

   // 2-D array
   int arr2D[row][col];

   // one dimensional array
   for(i = 0; i < size; ++i){
      arr[i] = rand() % 100 + 1;
   }

   // two dimensional array
   for(i = 0; i < row; ++i){
      for(j = 0; j < col; ++j){
         arr2D[i][j] = rand() % 100 + 1;
      }
   }

   // printing arrays
   printf("One-dimensional array:\n");

   // oneDArray(size, arr);
   for(i = 0; i < size; ++i)
   printf("a[%d]: %d\n", i, arr[i]);
   printf("\nTwo-dimensional array:\n");

   // twoDArray(row1, col1, arr2D);
   for(i = 0; i < row; ++i){
      printf("\n");
      for (j = 0; j < col; ++j)
         printf("%5d", arr2D[i][j]);
   }
}

运行代码并检查其输出:

Enter the size of one-dimensional array: 5
Enter the number of rows & columns of 2-D array:
4 4
One-dimensional array:
a[0]: 95
a[1]: 93
a[2]: 4
a[3]: 52
a[4]: 68

Two-dimensional array:
   92   19   79   23
   56   21   44   98
    8   22   89   54
   93    1   63   38

Jagged Array

锯齿状数组是类似数据类型具有可变长度的两个或更多数组的集合。在 C 中,锯齿状数组的概念使用 pointers of arrays 实现。

锯齿状数组用下图表示:

a jagged array

Example

在此程序中,我们声明了三个不同大小的一维数组,并将它们的指针存储在数组指针中,它充当锯齿状数组。

#include <stdio.h>

int main(){

   int a[] = {1,2};
   int b[] = {3,4,5};
   int c[] = {6,7,8,9};

   int l1 = sizeof(a)/sizeof(int),
   l2 = sizeof(b)/sizeof(int),
   l3 = sizeof(c)/sizeof(int);

   int *arr[] = {a,b,c};
   int size[] = {l1, l2, l3};
   int *ptr;
   int i, j, k = 0;

   for(i = 0; i < 3; i++){
      ptr = arr[i];
      for(j = 0; j < size[k]; j++){
         printf("%d\t", *ptr);
         ptr++;
      }
      printf("\n");
      k++;
      arr[i]++;
   }

   return 0;
}

当你运行这段代码时,它将产生以下输出:

1       2
3       4       5
6       7       8       9

与堆分配相比,VLA 是一种快速且更直接的选择。大多数现代 C 编译器(如 GCC、Clang 等)支持 VLA,并且大多数编译器也在使用它们。