可變長數組
可變長數組是指在計算機程序設計中,數組對象的長度在運行時(而不是編譯時)確定。[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