C語言中的變長陣列



C語言中的變長陣列也稱為變尺寸陣列或執行時尺寸陣列。它是一個長度在執行時確定而不是在編譯程式時確定的陣列。其大小取決於程式執行期間生成的、通常從使用者那裡接收到的輸入值。

通常,陣列大小在程式中預先宣告如下:

int arr[10];

一旦宣告,陣列的大小在程式執行期間保持固定,並且不能在執行時更改。但是,對於變長陣列(VLA),編譯器會在堆疊上分配具有自動儲存期的記憶體。對VLA的支援是在C99標準中新增的。

建立變長陣列

建立變長陣列的語法如下:

void arr_init(int length){

   int arr[length];

   //code using arr;

};

示例

下面的例子演示瞭如何建立一個變長陣列:

#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

二維變長陣列

我們還可以宣告和使用二維變長陣列。

示例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

示例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 ....

示例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

鋸齒陣列

鋸齒陣列是兩個或多個具有相同資料型別但長度可變的陣列的集合。在C語言中,鋸齒陣列的概念是藉助於陣列指標實現的。

鋸齒陣列由下圖表示:

A Jagged Array

示例

在這個程式中,我們聲明瞭三個大小不同的單維陣列,並將它們的指標儲存在一個指標陣列中,該指標陣列充當鋸齒陣列。

#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,並且大多數編譯器都使用VLA。

廣告
© . All rights reserved.