Matriz de longitud variable

Tipo de estructura de datos

En programación informática , una matriz de longitud variable ( VLA ), también llamada de tamaño variable o de tamaño en tiempo de ejecución , es una estructura de datos de matriz cuya longitud se determina en tiempo de ejecución , en lugar de en tiempo de compilación . [1] En el lenguaje C , se dice que la VLA tiene un tipo de datos modificado de forma variable que depende de un valor (ver Tipo dependiente ).

El propósito principal de los VLA es simplificar la programación de algoritmos numéricos .

Los lenguajes de programación que admiten VLA incluyen Ada , ALGOL 68 (para filas no flexibles), APL , C99 (aunque posteriormente relegado en C11 a una característica condicional, que las implementaciones no están obligadas a admitir; [2] [3] en algunas plataformas, los VLA se podían implementar anteriormente con alloca()o funciones similares) y C# (como matrices asignadas a la pila en modo inseguro ), COBOL , Fortran 90, J y Object Pascal (el lenguaje utilizado en Delphi y Lazarus , que utiliza FPC).

Las matrices ampliables (también llamadas matrices dinámicas ) son generalmente más útiles que las matrices de longitud variable porque las matrices dinámicas pueden hacer todo lo que las matrices de longitud variable pueden hacer y también admiten el crecimiento de la matriz en tiempo de ejecución. Por esta razón, muchos lenguajes de programación ( JavaScript , Java , Python , R , etc.) solo admiten matrices ampliables. Incluso en lenguajes que admiten matrices de longitud variable, a menudo se recomienda evitar el uso de matrices de longitud variable (basadas en pila) y, en su lugar, utilizar matrices dinámicas ( basadas en montón ). [4]

Memoria

Asignación

Implementación

C99

La siguiente función C99 asigna una matriz de longitud variable de un tamaño especificado, la llena con valores de punto flotante y luego la pasa a otra función para su procesamiento. Debido a que la matriz se declara como una variable automática, su duración finaliza cuando read_and_process()retorna.

flotante leer_y_procesar ( int n ) { flotante vals [ 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 ir antes del parámetro de matriz de longitud variable en las llamadas de función. [1] En C11, __STDC_NO_VLA__se define una macro si no se admite VLA. [6] El estándar C23 vuelve a hacer obligatorios los tipos VLA. Solo la creación de objetos VLA con duración de almacenamiento automática es opcional. [7] GCC tenía VLA como una extensión antes de C99, una que también se extiende a su dialecto C++.

Linus Torvalds ha expresado en el pasado su descontento con el uso de VLA para matrices con tamaños pequeños predeterminados porque genera código ensamblador de menor calidad. [8] Con el kernel Linux 4.20, el kernel Linux está efectivamente libre de VLA. [9]

Aunque C11 no nombra explícitamente un límite de tamaño para los VLA, algunos creen que debería tener el mismo tamaño máximo que todos los demás objetos, es decir, SIZE_MAX bytes. [10] Sin embargo, esto debería entenderse en el contexto más amplio de los límites del entorno y la plataforma, como el tamaño de página de protección de pila típico de 4 KiB, que es muchos órdenes de magnitud más pequeño que SIZE_MAX.

Es posible tener un objeto VLA con almacenamiento dinámico utilizando un puntero a una matriz.

flotante leer_y_procesar ( int n ) { flotante ( * vals )[ n ] = malloc ( sizeof ( float [ n ]));       para ( int i = 0 ; i < n ; ++ i ) ( * vals )[ i ] = read_val ();            float ret = proceso ( n , * vals ); libre ( vals ); devolver ret ; }         

Ada

El siguiente es el mismo ejemplo en Ada . Las matrices de Ada llevan consigo sus límites, por lo que no es necesario pasar la longitud a la función Process.

tipo  Vals_Type  es  una matriz  ( rango positivo  <>) de flotante ;   función  Read_And_Process  ( N  : Integer )  retorna  Float  es  Vals  :  Vals_Type  ( 1..N  ) ; comienza para I en 1..N bucle Vals ( I ) : = Read_Val ; fin del bucle ; retorna  Proceso ( Vals ) ; fin Read_And_Process ;                 

Fortran 90

La función equivalente de Fortran 90 es

función leer_y_procesar ( n ) resultado ( o ) entero , intención ( en ) :: n real :: o    real , dimensión ( n ) :: vals entero :: i  hacer i = 1 , n vals ( i ) = leer_val () fin hacer o = proceso ( vals ) fin función leer_y_procesar         

al utilizar la característica Fortran 90 de verificar interfaces de procedimientos en tiempo de compilación; por otro lado, si las funciones usan una 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    hacer i = 1 , n vals ( i ) = leer_val () fin hacer o = proceso ( vals , n ) fin función leer_y_procesar         

Cobol

El siguiente fragmento de COBOL declara una matriz de registros de longitud variable DEPT-PERSONque tiene una longitud (número de miembros) especificada por el valor de PEOPLE-CNT:

DIVISIÓN DE DATOS . SECCIÓN DE TRABAJO-ALMACENAMIENTO . 01 DEPT-PERSONAS . 05 PERSONAS-CNT PIC S9(4) BINARIO . 05 DEPT-PERSONA OCURRE DE 0 A 20 VECES DEPENDIENDO DE PERSONAS-CNT . 10 PERSONA-NOMBRE PIC X(20) . 10 PERSONA-SALARIO PIC S9(7)V99 PAQUETE-DECIMAL .                 

A diferencia de otros lenguajes mencionados aquí, el VLA de COBOLDEPT-PERSON es seguro porque COBOL requiere especificar el tamaño máximo de la matriz. En este ejemplo, no puede tener más de 20 elementos, independientemente del valor de PEOPLE-CNT.

DO#

El siguiente fragmento de C# declara una matriz de longitud variable de números enteros. Antes de la versión 7.2 de C#, se requería un puntero a la matriz, lo que requería un contexto "inseguro". La palabra clave "inseguro" requiere que un ensamblaje que contenga este código se marque como inseguro.

void inseguro DeclareStackBasedArrayUnsafe ( int tamaño ) { int * pArray = stackalloc int [ tamaño ]; pArray [ 0 ] = 123 ; }           

La versión 7.2 de C# y posteriores permiten que la matriz se asigne sin la palabra clave "unsafe", mediante el uso de la función Span. [11]

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

Objeto Pascal

Las matrices dinámicas de Object Pascal se asignan en el montón. [12]

En este lenguaje, se denomina matriz dinámica. La declaración de una variable de este tipo es similar a la declaración de una matriz estática, pero sin especificar su tamaño. El tamaño de la matriz se indica en el momento de su uso.

programa CreateDynamicArrayOfNumbers ( Tamaño : Entero ) ; var NumberArray : matriz de LongWord ; comienzo SetLength ( NumberArray , Tamaño ) ; NumberArray [ 0 ] := 2020 ; fin .           

La eliminación del contenido de una matriz dinámica se realiza asignándole un tamaño de cero.

... EstablecerLongitud ( NumberArray , 0 ) ; ... 

Referencias

  1. ^ ab "Matrices de longitud variable". Archivado desde el original el 26 de enero de 2018.
  2. ^ "Longitud variable: uso de la colección de compiladores GNU (GCC)".
  3. ^ ISO 9899:2011 Lenguajes de programación – C 6.7.6.2 4.
  4. ^ Raymond, Eric S. (2000). "Prácticas de lanzamiento de software de Raymond: 6. Buenas prácticas de desarrollo". Proyecto de documentación de Linux .
  5. ^ "Opciones de generación de código: el compilador GNU Fortran".
  6. ^ § 6.10.8.3 de la norma C11 (n1570.pdf)
  7. ^ § 6.10.9.3 de la norma C23 (n3054.pdf)
  8. ^ Torvalds, Linus (7 de marzo de 2018). "LKML: Linus Torvalds: Re: Eliminación de VLA (antes Re: [RFC 2/2] lustre: usar VLA_SAFE)". Kernel de Linux (lista de correo).
  9. ^ "El kernel de Linux ahora está libre de VLA: una victoria para la seguridad, menos sobrecarga y mejor para Clang - Phoronix". www.phoronix.com .
  10. ^ §6.5.3.4 y §7.20.3 de la norma C11 (n1570.pdf)
  11. ^ "Operador stackalloc (referencia de C#)". Microsoft. 10 de julio de 2024.
  12. ^ Michaël Van Canneyt. "Guía de referencia de Free Pascal: matrices dinámicas".
Obtenido de "https://es.wikipedia.org/w/index.php?title=Matriz_de_longitud_variable&oldid=1253333370"