V programování je pole proměnné délky ( VLA, pole proměnné velikosti, pole velikosti runtime ) pole , jehož délka je určena v době běhu (a ne v době kompilace) [1] . V C má pole s proměnnou délkou typ spravovaný proměnnou ( angl. variabilně modifikovaný typ ), který závisí na nějaké hodnotě (viz Závislý typ ).
Hlavním účelem polí proměnné délky je zjednodušit programování numerických algoritmů.
Programovací jazyky, které podporují pole s proměnnou délkou: Ada , Algol 68 (bez možnosti měnit délku řetězců ve dvourozměrných polích atd.), APL , C99 (ačkoli později se pole s proměnnou délkou stalo volitelnou funkcí v C11 , jehož podpora není vyžadována [2] [3] ; na některých platformách to mohlo být již dříve implementováno pomocí funkce alloca()nebo podobně) a C# (pole alokovaná na zásobníku – tato funkce je dostupná pouze v nebezpečném režimu), COBOL , Fortran 90 , J a Object Pascal (jazyk používaný v prostředí LazarusaBorland Delphi , zkompilovaný pomocí kompilátoru Free Pascal).
Následující funkce C99 alokuje pole s proměnnou délkou dané velikosti, naplní je hodnotami s plovoucí desetinnou čárkou a poté je předá jiné funkci ke zpracování. Protože je pole deklarováno jako automatická proměnná, jeho životnost končí, když read_and_process().
float read_and_process ( int n ) { plovákové valy [ n ]; for ( int i = 0 ; i < n ; ++ i ) val [ i ] = read_val (); návratový proces ( n , val ); }V C99 musí parametr length předcházet parametru pole proměnné délky ve volání funkcí [1] . C11 definuje makro __STDC_NO_VLA__, pokud pole s proměnnou délkou nejsou podporována [5] . GCC měl pole s proměnnou délkou jako rozšíření před C99, které také zasahuje do jeho dialektu C++.
Linus Torvalds v minulosti vyjádřil svou nespokojenost s používáním malých polí s proměnnou délkou, protože to generuje nižší kvalitu kódu montáže [6] . Linuxové jádro 4.20 ve skutečnosti neobsahuje pole s proměnnou délkou [ 7] .
Ačkoli C11 výslovně neuvádí limit velikosti pro pole s proměnnou délkou, některé interpretace naznačují, že by měly mít stejnou maximální velikost jako všechny ostatní objekty, tzn. SIZE_MAXbyte [8] . Tuto interpretaci je však nutné chápat v širším kontextu omezení prostředí a platformy, jako je typická velikost stránky s ochranou zásobníku 4 kB, což je o mnoho řádů menší než SIZE_MAX.
Můžete použít syntaxi podobnou poli s proměnnou délkou s dynamickým úložištěm pomocí ukazatele na pole.
float read_and_process ( int n ) { float ( * vals )[ n ] = malloc ( sizeof ( float [ n ])); for ( int i = 0 ; i < n ; ++ i ) ( * vals )[ i ] = read_val (); float ret = proces ( n , * val ); zdarma ( val ); vrátit ret ; }Níže je stejný příklad v Ada . Pole obsahují svou délku spolu s daty, takže není potřeba předávat jejich délku funkci Process.
type Vals_Type je pole ( Positive range <>) of Float ; funkce Read_And_Process ( N : Integer ) return Float is Vals : Vals_Type ( 1 .. N ); begin for I in 1 .. N loop Vals ( I ) := Read_Val ; konec -smyčka ; návratový proces ( Vals ); end Read_And_Process ;Ekvivalentní funkce v jazyce Fortran 90 .
funkce read_and_process ( n ) result ( o ) integer , intent ( in ) :: n real :: o reálná , dimenze ( n ) :: vals integer :: i do i = 1 , n vals ( i ) = read_val ( ) end do o = proces ( val ) end function read_and_processPoužívá funkci Fortran 90 k testování rozhraní procedur v době kompilace; na druhou stranu, pokud funkce používají volací rozhraní před Fortran 90, musí být (externí) funkce deklarovány jako první a délka pole musí být explicitně předána jako argument (jako v C):
funkce read_and_process ( n ) result ( o ) integer , intent ( in ) :: n real :: o real , dimenze ( n ) :: vals real :: read_val , process integer :: i do i = 1 , n vals ( i ) = read_val ( ) end do o = proces ( val , n ) end function read_and_processNásledující fragment COBOL deklaruje pole záznamů s proměnnou délkou DEPT-PERSONdélky (počet prvků) dané PEOPLE-CNT:
DIVIZE DAT . PRACOVNĚ-SKLADOVACÍ ČÁST . 01 DEPT-LIDÉ . 05 PEOPLE-CNT PIC S9(4) BINARY . 05 DEPT-PERSON SE VYSKYTUJE 0 AŽ 20 KRÁT V ZÁVISLOSTI NA LIDECH-CNT . 10 JMÉNO OSOBY OBRÁZEK X(20) . 10 OSOBNÍ MZDA OBR. S9(7)V99 BALENO-DECIMAL .Pole s proměnnou délkou v COBOL jsou na rozdíl od ostatních zde zmíněných jazyků bezpečná, protože COBOL vyžaduje, abyste zadali maximální velikost pole – v tomto příkladu DEPT-PERSONnemůže obsahovat více než 20 prvků, bez ohledu na hodnotu PEOPLE-CNT.
Následující fragment C# deklaruje pole celých čísel s proměnnou délkou. Před C# 7.2 byl v „nebezpečném“ kontextu vyžadován ukazatel na pole. Klíčové slovo unsafevyžaduje, aby sestavení obsahující tento kód bylo označeno jako nebezpečné.
unsafe void DeclareStackBasedArrayUnsafe ( int size ) { int * pArray = stackalloc int [ size ]; pArray [ 0 ] = 123 ; }C# verze 7.2 a novější vám umožňuje alokovat pole bez klíčového slova unsafepomocí funkce Span [9] .
void DeclareStackBasedArraySafe ( int size ) { Span < int > stackArray = stackalloc int [ velikost ]; stackArray [ 0 ] = 123 ; }V tomto jazyce se pole s proměnnou délkou nazývá dynamické pole. Deklarování takové proměnné je podobné jako deklarace statického pole, ale bez určení jeho velikosti. Velikost pole je nastavena v době, kdy se používá.
program CreateDynamicArrayOfNumbers ( Size : Integer ) ; var NumberArray : pole LongWord ; _ begin SetLength ( NumberArray , Size ) ; NumberArray [ 0 ] := 2020 ; konec .Odstranění obsahu dynamického pole se provádí tak, že mu přidělíte velikost nula.
... SetLength ( NumberArray , 0 ) ; ...