可變長陣列

可變長陣列是指在電腦程式設計中,陣列對象的長度在執行時(而不是編譯時)確定。[1]

支援可變長陣列的程式設計語言有:Ada, ALGOL 68 (for non-flexible rows), APL, C99 (以及C11[2][3][4] ) ,C# [5], COBOL, Fortran 90, J

C/C++的靈活陣列類型(又稱柔性陣列成員)是另外一個語言特性。

可增長陣列(也叫做動態陣列)是不同的概念,很多程式語言比如JavaScriptJavaPythonR等只支援可增長陣列。

語言細節

C99

下述C99函式內部建立了一個可變長陣列的局部變數。因為該陣列被聲明為一個局部變數,所以它會在read_and_process函式返回時自動銷毀。

float read_and_process(int n)
{
    float vals[n];

    for (int i = 0; i < n; i++)
        vals[i] = read_val();
    return process(vals, n);
}

在C99中,進行函式呼叫時,變長陣列的長度必須在變長陣列本身之前進行傳入。在C11中,如果編譯器不支援VLA(變長陣列)的話,編譯器本身會定義一個叫做__STDC_NO_VLA__的宏。在C99之前,GCC就已經把VLA作為一個有用的擴充了。

但是Linus Torvalds表達了對可以預見長度的小陣列仍然使用VLA(變長陣列)的情況不太滿意,並(在一段加密程式碼中)寫下如下注釋:「USING VLA'S IS ACTIVELY STUPID! It generates much more code, and much slower code (and more fragile code), than just using a fixed key size would have done.」(相比單純使用一個固定的金鑰長度,使用變長陣列太蠢了,因為它生成的機器碼多得多,執行起來慢得多(維護起來還更容易出問題))。有鑑於此,Linux kernel專案從頭到尾都沒有使用過一處變長陣列。

C++

C++0x標準不支援變長陣列[6]

但是作為一個有用的擴充,g++和clang++對VLA做了一些支援(但請注意,它並不是標準化的一部分)。

作為替代,建議使用C++標準下的STL容器std::vector,或者使用new和delete[]來動態地為陣列分配主記憶體。

其他

同樣的功能用Ada表示:

type Vals_Type is array (Positive range <>) of Float;

function Read_And_Process (N : Integer) return Float is
   Vals : Vals_Type (1 .. N);
begin
   for I in 1 .. N loop
      Vals (I) := Read_Val;
   end loop;
   return Process (Vals);
end Read_And_Process;

等價的Fortran 90函式:

function read_and_process(n) result(o)
    integer,intent(in)::n
    real::o

    real,dimension(n)::vals
    real::read_val, process
    integer::i
 
    do i = 1,n
       vals(i) = read_val()
    end do
    o = process(vals, n)
end function read_and_process

COBOL代碼片段:

DATA DIVISION.
WORKING-STORAGE SECTION.
01  DEPT-PEOPLE.
    05  PEOPLE-CNT          PIC S9(4) BINARY.
    05  DEPT-PERSON         OCCURS 0 TO 20 TIMES DEPENDING ON PEOPLE-CNT.
        10  PERSON-NAME     PIC X(20).
        10  PERSON-WAGE     PIC S9(7)V99 PACKED-DECIMAL.

C#函式:

unsafe void declareStackBasedArray(int size)
{
    int *pArray = stackalloc int[size];
    pArray[0] = 123;
}

參考文獻

  1. ^ 存档副本. [2014-12-19]. (原始內容存檔於2018-04-03). 
  2. ^ http://pic.dhe.ibm.com/infocenter/ratdevz/v8r0/topic/com.ibm.xlcpp111.aix.doc/language_ref/variable_length_arrays.html
  3. ^ 存档副本. [2014-12-19]. (原始內容存檔於2020-12-05). 
  4. ^ ISO 9899:2011 Programming Languages - C 6.7.6.2 4
  5. ^ 作為unsafe-mode stack-allocated arrays
  6. ^ https://stackoverflow.com/questions/1887097