En programación , una matriz de longitud variable ( VLA, matriz de tamaño variable, matriz de tamaño de tiempo de ejecución ) es una matriz cuya longitud se determina en tiempo de ejecución (y no en tiempo de compilación) [1] . En C, una matriz de longitud variable tiene un tipo de gestión variable ( ing. tipo modificado de forma variable ), que depende de algún valor (consulte Tipo dependiente ).
El objetivo principal de las matrices de longitud variable es simplificar la programación de algoritmos numéricos.
Lenguajes de programación que admiten matrices de longitud variable: Ada , Algol 68 (sin la capacidad de cambiar la longitud de las cadenas en matrices bidimensionales, etc.), APL , C99 (aunque más tarde la matriz de longitud variable se convirtió en una característica opcional en C11 , cuyo soporte no es necesario [2] [3] ; en algunas plataformas esto puede haberse implementado previamente con una función alloca()o similar) y C# (matrices asignadas en la pila; esta característica solo está disponible en modo no seguro), COBOL , Fortran 90 , J y Object Pascal (el lenguaje utilizado en los entornos LazarusyBorland Delphi , compilado con Free Pascal Compiler).
La siguiente función C99 asigna una matriz de longitud variable de un tamaño determinado, la llena con valores de coma flotante y luego la pasa a otra función para su procesamiento. Dado que la matriz se declara como una variable automática, su vida útil finaliza cuando read_and_process().
float leer_y_procesar ( int n ) { valores flotantes [ n ]; para ( int i = 0 ; i < n ; ++ i ) vals [ i ] = read_val (); proceso de retorno ( n , vals ); }En C99, el parámetro de longitud debe preceder al parámetro de matriz de longitud variable en las llamadas de función [1] . C11 define una macro __STDC_NO_VLA__si no se admiten matrices de longitud variable [5] . GCC tenía matrices de longitud variable como una extensión antes de C99, que también se extiende a su dialecto C++.
Linus Torvalds ha expresado su descontento en el pasado con el uso de matrices pequeñas de longitud variable, ya que esto genera un código ensamblador de menor calidad [6] . El kernel de Linux 4.20 en realidad no contiene arreglos de longitud variable [ 7] .
Aunque C11 no establece explícitamente un límite de tamaño para las matrices de longitud variable, algunas interpretaciones sugieren que deberían tener el mismo tamaño máximo que todos los demás objetos, es decir, SIZE_MAXbyte [8] . Sin embargo, esta interpretación debe entenderse en el contexto más amplio de las limitaciones del entorno y la plataforma, como un tamaño de página típico con protección de pila de 4 KiB, que es muchos órdenes de magnitud más pequeño que SIZE_MAX.
Puede usar una sintaxis similar a una matriz de longitud variable con almacenamiento dinámico usando un puntero a una matriz.
float leer_y_procesar ( int n ) { float ( * vals )[ n ] = malloc ( sizeof ( float [ n ])); para ( int i = 0 ; i < n ; ++ i ) ( * vals )[ i ] = read_val (); float ret = proceso ( n , * vals ); libre ( vals ); volver ret ; }A continuación se muestra el mismo ejemplo en Ada . Las matrices contienen su longitud junto con los datos, por lo que no es necesario pasar su longitud a la función Process.
type Vals_Type es una matriz ( rango positivo <>) de Float ; función Read_And_Process ( N : Integer ) return Float is Vals : Vals_Type ( 1 .. N ); comenzar por I en 1 .. N loop Vals ( I ) := Read_Val ; bucle final ; Proceso de retorno ( Vals ); end Leer_y_procesar ;Función equivalente en lenguaje Fortran 90 .
función leer_y_procesar ( n ) resultado ( o ) entero , intención ( en ) :: n real :: o real , dimensión ( n ) :: vals entero :: i do i = 1 , n vals ( i ) = read_val () end do o = proceso ( vals ) fin función read_and_processUtiliza la función Fortran 90 para probar las interfaces de procedimiento en tiempo de compilación; por otro lado, si las funciones usan la interfaz de llamada anterior a Fortran 90, las funciones (externas) deben declararse primero y la longitud de la matriz debe pasarse explícitamente como argumento (como en C):
función leer_y_procesar ( n ) resultado ( o ) entero , intención ( en ) :: n real :: o real , dimensión ( n ) :: vals real :: read_val , proceso entero :: i do i = 1 , n vals ( i ) = read_val () end do o = proceso ( vals , n ) end function leer_y_procesarEl siguiente fragmento de COBOL declara una matriz de registros de longitud variable de DEPT-PERSONlongitud (número de elementos) dada por PEOPLE-CNT:
DIVISIÓN DE DATOS . SECCIÓN DE TRABAJO-ALMACENAJE . 01 DEPARTAMENTO-PERSONAS . 05 PERSONAS-CNT PIC S9(4) BINARIO . 05 DEPT-PERSONA OCURRE DE 0 A 20 VECES DEPENDIENDO DE LAS PERSONAS-CNT . 10 NOMBRE-PERSONA FOTO X(20) . 10 PERSONA-SALARIO PIC S9(7)V99 EMPAQUETADO -DECIMAL .Las matrices de longitud variable en COBOL , a diferencia de los otros lenguajes mencionados aquí, son seguras porque COBOL requiere que especifique un tamaño máximo de matriz; en este ejemplo, DEPT-PERSONno puede contener más de 20 elementos, independientemente del valor de PEOPLE-CNT.
El siguiente fragmento de C# declara una matriz de enteros de longitud variable. Antes de C# 7.2, se requería un puntero a una matriz en un contexto "inseguro". La palabra clave unsaferequiere que el ensamblado que contiene este código se marque como no seguro.
unsafe void DeclareStackBasedArrayUnsafe ( int size ) { int * pArray = stackalloc int [ size ]; pMatriz [ 0 ] = 123 ; }C# versión 7.2 y posteriores le permiten asignar una matriz sin la palabra clave unsafemediante la función Span [9] .
void DeclareStackBasedArraySafe ( tamaño int ) { Span < int > stackArray = stackalloc int [ tamaño ]; apilarArray [ 0 ] = 123 ; }En este lenguaje, una matriz de longitud variable se denomina matriz dinámica. Declarar una variable de este tipo es similar a declarar una matriz estática, pero sin especificar su tamaño. El tamaño de una matriz se establece en el momento en que se utiliza.
programa CreateDynamicArrayOfNumbers ( Tamaño : Entero ) ; var NumberArray : matriz de LongWord ; comenzar SetLength ( NumerArray , Tamaño ) ; MatrizNumérica [ 0 ] := 2020 ; fin _La eliminación del contenido de una matriz dinámica se realiza dándole un tamaño de cero.
... EstablecerLongitud ( NumerArray , 0 ) ; ...