可變長陣列
可變長陣列是指在電腦程式設計中,陣列對象的長度在執行時(而不是編譯時)確定。[1]
支援可變長陣列的程式設計語言有:Ada, ALGOL 68 (for non-flexible rows), APL, C99 (以及C11[2][3][4] ) ,C# [5], COBOL, Fortran 90, J。
C/C++的靈活陣列類型(又稱柔性陣列成員)是另外一個語言特性。
可增長陣列(也叫做動態陣列)是不同的概念,很多程式語言比如JavaScript、Java、Python和R等只支援可增長陣列。
語言細節
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;
}
參考文獻
- ^ 存档副本. [2014-12-19]. (原始內容存檔於2018-04-03).
- ^ http://pic.dhe.ibm.com/infocenter/ratdevz/v8r0/topic/com.ibm.xlcpp111.aix.doc/language_ref/variable_length_arrays.html
- ^ 存档副本. [2014-12-19]. (原始內容存檔於2020-12-05).
- ^ ISO 9899:2011 Programming Languages - C 6.7.6.2 4
- ^ 作為unsafe-mode stack-allocated arrays
- ^ https://stackoverflow.com/questions/1887097