stringtranslate.com

Matriz de longitud variable

En programación de computadoras , una matriz de longitud variable ( VLA ), también llamada de tamaño variable o de tamaño de 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 el VLA tiene un tipo de datos modificado de forma variable que depende de un valor (consulte Tipo dependiente ).

El objetivo 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 relegados en C11 a una característica condicional, cuyas implementaciones no están obligadas a admitir; [2] [3] en algunas plataformas, Los VLA se podían implementar anteriormente con alloca()funciones similares o similares) y C# (como matrices asignadas a pila en modo inseguro ), COBOL , Fortran 90, J y Object Pascal (el lenguaje utilizado en Delphi y Lazarus , que usa FPC).

Los arreglos cultivables (también llamados arreglos dinámicos ) son generalmente más útiles que los VLA porque los arreglos dinámicos pueden hacer todo lo que los VLA pueden hacer y también admiten el crecimiento del arreglo en tiempo de ejecución. Por esta razón, muchos lenguajes de programación ( JavaScript , Java , Python , R , etc.) solo admiten matrices cultivables. 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 específico, 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 vida útil finaliza cuando read_and_process()regresa.

float read_and_process ( 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 aparecer antes del parámetro de matriz de longitud variable en las llamadas a funciones. [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. Sólo la creación de objetos VLA con duración de almacenamiento automático 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 su descontento en el pasado por el uso de VLA para arreglos con tamaños pequeños predeterminados porque genera código ensamblador de menor calidad. [8] Con el kernel Linux 4.20, el kernel de 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, TAMAÑO_MAX bytes. [10] Sin embargo, esto debe entenderse en el contexto más amplio de los límites del entorno y la plataforma, como el tamaño típico de página de protección de pila de 4 KiB, que es muchos órdenes de magnitud más pequeño que TAMAÑO_MAX.

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

float read_and_process ( 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 atrás ; }         

ada

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

el tipo  Vals_Type  es  una matriz  ( rango positivo  <>) de Float ;   función  Read_And_Process  ( N  : Integer )  return  Float  es  Vals  :  Vals_Type  ( 1  ..  N ); comenzar  para  I  en  1  ..  N  bucle  Vals  ( I )  : =  Read_Val ;  bucle final  ; Proceso de devolución ( Vals ); finalizar Read_And_Process ;    

Fortran 90

La función equivalente de Fortran 90 es

función read_and_process ( n ) resultado ( o ) entero , intención ( in ) :: n real :: o    real , dimensión ( n ) :: vals entero :: i  do i = 1 , n vals ( i ) = read_val () fin do o = proceso ( vals ) fin de la función read_and_process         

cuando se utiliza la función Fortran 90 para verificar las interfaces de procedimientos en tiempo de compilación; por otro lado, si las funciones usan una interfaz de llamada anterior a Fortran 90, primero se deben declarar las funciones (externas) y la longitud de la matriz se debe pasar explícitamente como argumento (como en C):

función read_and_process ( n ) resultado ( o ) entero , intención ( in ) :: n real :: o    real , dimensión ( n ) :: vals real :: read_val , entero de proceso :: i    hacer i = 1 , n vals ( i ) = read_val () finalizar hacer o = proceso ( vals , n ) finalizar la función read_and_process         

Cobol

El siguiente fragmento 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 DEPARTAMENTO-PERSONAS . 05 PUEBLO-CNT PIC S9(4) BINARIO . 05 DEPTO-PERSONA OCURRE 0 A 20 VECES DEPENDIENDO DE LAS PERSONAS-CNT . 10 NOMBRE DE PERSONA FOTO X(20) . 10 FOTO DE SALARIO PERSONAL S9(7)V99 EMPAQUETADO-DECIMAL .                 

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

C#

El siguiente fragmento de C# declara una matriz de números enteros de longitud variable. 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 ensamblado que contenga este código se marque como inseguro.

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

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

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

Objeto Pascal

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

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

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

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

... EstablecerLongitud ( NúmeroArray , 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. ^ Lenguajes de programación ISO 9899:2011 - C 6.7.6.2 4.
  4. ^ Raymond, Eric S. (2000). "Cómo práctica de lanzamiento de software de Raymond: 6. Buenas prácticas de desarrollo". El proyecto de documentación de Linux .
  5. ^ "Opciones de generación de código: el compilador GNU Fortran".
  6. ^ § 6.10.8.3 del estándar C11 (n1570.pdf)
  7. ^ § 6.10.9.3 del estándar C23 (n3054.pdf)
  8. ^ Torvalds, Linus (7 de marzo de 2018). "LKML: Linus Torvalds: Re: eliminación de VLA (era Re: [RFC 2/2] brillo: usar VLA_SAFE)". Kernel de Linux (lista de correo).
  9. ^ "El kernel de Linux ahora no tiene VLA: una victoria para la seguridad, menos gastos generales y mejor para Clang - Phoronix". www.phoronix.com .
  10. ^ §6.5.3.4 y §7.20.3 del estándar C11 (n1570.pdf)
  11. ^ "operador stackalloc (referencia de C#)". Microsoft.
  12. ^ Michael Van Canneyt. "Guía de referencia gratuita de Pascal: matrices dinámicas".