Variabel længde array

I programmering er et array med variabel længde ( VLA, array med variabel størrelse, array i runtime-størrelse ) et array , hvis længde bestemmes ved kørselstid (og ikke ved kompilering) [1] . I C har et array med variabel længde en variabel-styret type ( eng. variably modified type ), som afhænger af en eller anden værdi (se Afhængig type ).   

Hovedformålet med arrays af variabel længde er at forenkle programmeringen af ​​numeriske algoritmer.

Programmeringssprog, der understøtter arrays med variabel længde: Ada , Algol 68 (uden mulighed for at ændre længden af ​​strenge i todimensionelle arrays osv.), APL , C99 (selvom senere arrayet med variabel længde blev en valgfri funktion i C11 , som ikke er påkrævet [2] [3] ; på nogle platforme kan dette være implementeret tidligere med en funktion alloca()eller lignende) og C# (arrays allokeret på stakken - denne funktion er kun tilgængelig i usikker tilstand), COBOL , Fortran 90 , J og Object Pascal (sproget, der bruges af i miljøerBorland Delphi og Lazarus kompilerer med Free Pascal Compiler).

Hukommelse

Hukommelsestildeling

Implementering

C99

Den følgende C99- funktion tildeler et array med variabel længde af en given størrelse, fylder det med flydende kommaværdier og sender det derefter til en anden funktion til behandling. Da arrayet er erklæret som en automatisk variabel, slutter dens levetid, når read_and_process().

float read_and_process ( int n ) { flydevals [ n ] ; for ( int i = 0 ; i < n ; ++ i ) vals [ i ] = read_val (); returproces ( n , vals ) ; }

I C99 skal længdeparameteren gå foran parameteren variabel længde array i funktionskald [1] . C11 definerer en makro __STDC_NO_VLA__, hvis arrays med variabel længde ikke understøttes [5] . GCC havde arrays med variabel længde som en udvidelse før C99, som også strækker sig til dens C++ dialekt.

Linus Torvalds har tidligere udtrykt sin utilfredshed med brugen af ​​små arrays med variabel længde, da dette genererer en samlingskode af lavere kvalitet [6] . Linux 4.20-kernen indeholder faktisk ikke arrays med variabel længde [ 7] .

Selvom C11 ikke eksplicit angiver en størrelsesgrænse for arrays med variabel længde, tyder nogle fortolkninger på, at de bør have samme maksimale størrelse som alle andre objekter, dvs. SIZE_MAXbyte [8] . Denne fortolkning skal dog forstås i den bredere kontekst af miljø- og platformsbegrænsninger, såsom en typisk sidestørrelse med 4 KiB stakbeskyttelse, som er mange størrelsesordener mindre end SIZE_MAX.

Du kan bruge en array-lignende syntaks med variabel længde med dynamisk lagring ved hjælp af en markør til et array.

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 , * vals ); fri ( vals ); returnere ret ; }

Ada

Nedenfor er det samme eksempel i Ada . Arrays indeholder deres længde sammen med dataene, så der er ingen grund til at overføre deres længde til procesfunktionen.

type Vals_Type er array ( positivt område <>) af Float ; funktion Read_And_Process ( N : Heltal ) return Float er Vals : Vals_Type ( 1 .. N ); begynde for I i 1 .. N loop Vals ( I ) := Read_Val ; ende -løkke ; returproces ( Vals ) ; afslutte Read_And_Process ;

Fortran 90

Tilsvarende funktion i Fortran 90 sprog .

funktion read_and_process ( n ) resultat ( o ) heltal , hensigt ( in ) :: n reel :: o reel , dimension ( n ) :: vals heltal :: i do i = 1 , n vals ( i ) = read_val ( ) end do o = proces ( vals ) end funktion read_and_process

Bruger Fortran 90-funktionen til at teste proceduregrænseflader på kompileringstidspunktet; på den anden side, hvis funktionerne bruger pre-Fortran 90 kaldende grænseflade, skal de (eksterne) funktioner erklæres først, og længden af ​​arrayet skal udtrykkeligt videregives som et argument (som i C):

funktion read_and_process ( n ) resultat ( o ) heltal , hensigt ( in ) :: n reel :: o real , dimension ( n ) :: vals real :: read_val , proces heltal :: i do i = 1 , n vals ( i ) = read_val ( ) end do o = proces ( vals , n ) end function read_and_process

Cobol

Følgende COBOL -uddrag erklærer en registreringsmatrix med variabel længde af DEPT-PERSONlængde (antal elementer) givet af PEOPLE-CNT:

DATADIVISION . _ ARBEJDS-OPBEVARING AFSNIT . 01 DEPT-FOLK . 05 PEOPLE-CNT PIC S9(4) BINÆR . 05 DEPT-PERSON FOREKOMMER 0 TIL 20 GANGE AFHÆNGIG AF PEOPLE-CNT . 10 PERSONNAVN BILLEDE X(20) . 10 PERSON-LØN PIC S9(7)V99 PACKET -DECIMAL .

Variable-længde-arrays i COBOL , i modsætning til de andre sprog, der er nævnt her, er sikre, fordi COBOL kræver, at du angiver en maksimal matrixstørrelse - i dette eksempel må DEPT-PERSONden ikke indeholde mere end 20 elementer, uanset værdien af PEOPLE-CNT​​.

C#

Følgende C# -uddrag erklærer et array med variabel længde af heltal. Før C# 7.2 krævedes en pointer til et array i en "usikker" kontekst. Nøgleordet unsafekræver, at samlingen, der indeholder denne kode, er markeret som usikker.

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

C# version 7.2 og nyere giver dig mulighed for at allokere et array uden nøgleordet unsafeved hjælp af Span [9] funktionen .

void DeclareStackBasedArraySafe ( int size ) { Span < int > stackArray = stackalloc int [ size ]; stackArray [ 0 ] = 123 ; }

ObjectPascal

På dette sprog kaldes et array med variabel længde et dynamisk array. At erklære en sådan variabel svarer til at erklære et statisk array, men uden at specificere dets størrelse. Størrelsen af ​​et array indstilles på det tidspunkt, det bruges.

program CreateDynamicArrayOfNumbers ( Størrelse : Heltal ) ; var NumberArray : array af LongWord ; start SetLength ( NumberArray , Size ) ; NumberArray [ 0 ] := 2020 ; ende .

Sletning af indholdet af et dynamisk array sker ved at give det en størrelse på nul.

... SetLength ( NumberArray , 0 ) ; ...

Links

  1. 1 2 Arrays med variabel længde . Arkiveret fra originalen den 26. januar 2018.
  2. Variabel længde - Brug af GNU Compiler Collection (GCC) .
  3. ISO 9899:2011 Programmeringssprog - C 6.7.6.2 4.
  4. Code Gen Options - GNU Fortran Compiler .
  5. § 6.10.8.3 i C11-standarden (n1570.pdf)
  6. LKML: Linus Torvalds: Re: VLA-fjernelse (var Re: [RFC 2/2 glans: brug VLA_SAFE)] . lkml.org .
  7. ↑ Linux-kernen er nu VLA-fri : En gevinst for sikkerhed, mindre overhead og bedre for Clang - Phoronix  . www.phoronix.com .
  8. §6.5.3.4 og §7.20.3 i C11-standarden (n1570.pdf)
  9. stackalloc operator (C# reference) . Microsoft.