En programación de computadoras , el paso de una matriz (también conocido como incremento , paso o tamaño de paso ) es el número de ubicaciones en la memoria entre los comienzos de los elementos sucesivos de la matriz , medido en bytes o en unidades del tamaño de los elementos de la matriz. La zancada no puede ser menor que el tamaño del elemento, pero puede ser mayor, lo que indica un espacio adicional entre elementos.
Una matriz con un paso de exactamente el mismo tamaño que el tamaño de cada uno de sus elementos es contigua en la memoria. A veces se dice que tales matrices tienen pasos unitarios . Los arreglos de stride unitarios son a veces más eficientes que los arreglos de stride sin unidad, pero los arreglos de stride sin unidad pueden ser más eficientes para arreglos 2D o multidimensionales , dependiendo de los efectos del almacenamiento en caché y los patrones de acceso utilizados [ cita requerida ] . Esto se puede atribuir al principio de localidad , específicamente localidad espacial .
Razones para el paso sin unidad
Las matrices pueden tener un paso mayor que el ancho de sus elementos en bytes en al menos tres casos:
Relleno
Muchos lenguajes (incluidos C y C ++ ) permiten rellenar estructuras para aprovechar mejor la longitud de la palabra y / o el tamaño de la línea de caché de la máquina. Por ejemplo:
estructura A { int a ; char b ; };struct A myArray [ 100 ];
En el fragmento de código anterior, myArray
bien podría resultar tener un paso de ocho bytes, en lugar de cinco (4 bytes para el int más uno para el char), si el código C se compilara para una arquitectura de 32 bits , y el compilador había optimizado (como suele ser el caso) para un tiempo de procesamiento mínimo en lugar de un uso mínimo de memoria.
Arreglos paralelos superpuestos
Algunos lenguajes permiten que las matrices de estructuras se traten como matrices paralelas superpuestas con zancada sin unidad:
#include struct MyRecord { valor int ; char * texto ; }; / ** Imprime el contenido de una matriz de entradas con el paso dado. Tenga en cuenta que size_t es el tipo correcto, ya que int puede desbordarse. * / void print_some_ints ( const int * arr , int length , size_t stride ) { int i ; printf ( "Dirección \ t \ t Valor \ n " ); para ( i = 0 ; i < longitud ; ++ i ) { printf ( "% p \ t % d \ n " , arr , arr [ 0 ]); arr = ( int * ) (( carácter sin firmar * ) arr + zancada ); } } int main ( void ) { int ints [ 100 ] = { 0 }; struct MyRecord records [ 100 ] = { 0 }; print_some_ints ( & Ints [ 0 ], 100 , sizeof ints [ 0 ]); print_some_ints ( & registros [ 0 ]. valor , 100 , tamaño de los registros [ 0 ]); return 0 ; }
Este modismo es una forma de juego de palabras .
Sección transversal de la matriz
Algunos lenguajes como PL / I permiten lo que se conoce como una sección transversal de matriz , que selecciona ciertas columnas o filas de una matriz más grande. [1] : p.262 Por ejemplo, si una matriz bidimensional se declara como
declarar some_array ( 12 , 2 ) fijo ;
una matriz de una dimensión que consta solo de la segunda columna puede ser referenciada como
alguna_arreglo ( * , 2 )
Ejemplo de matriz multidimensional con zancada no unitaria
La zancada sin unidad es particularmente útil para imágenes. Permite crear subimágenes sin copiar los datos de píxeles. Ejemplo de Java:
public class GrayscaleImage { privado final int ancho , alto , anchoStride ; / ** Datos de píxeles. Los píxeles de una sola fila siempre se consideran contiguos en este ejemplo. * / bytes finales privados [] píxeles ; / ** Desplazamiento del primer píxel dentro de los píxeles * / desplazamiento int final privado ; / ** Constructor para datos contiguos * / público Imagen ( int ancho , int altura , byte [] píxeles ) { esto . ancho = ancho ; esto . altura = altura ; esto . píxeles = píxeles ; esto . desplazamiento = 0 ; esto . widthStride = ancho ; } / ** Constructor de subsección * / public Image ( int ancho , int alto , byte [] píxeles , int offset , int widthStride ) { this . ancho = ancho ; esto . altura = altura ; esto . píxeles = píxeles ; esto . offset = offset ; esto . widthStride = widthStride ; } / ** Devuelve una subregión de esta imagen como una nueva imagen. Esta y la nueva imagen comparten los píxeles, por lo que los cambios en la imagen devuelta se reflejarán en esta imagen. * / public Image crop ( int x1 , int y1 , int x2 , int y2 ) { return new Image ( x2 - x1 , y2 - y1 , píxeles , offset + y1 * widthStride + x1 , widthStride ); } / ** Devuelve el valor de píxel en la coordenada especificada * / byte público getPixelAt ( int x , int y ) { return píxeles [ offset + y * widthStride + x ] ; } }
Referencias
- ^ Hughes, Joan K (1979). Programación Estructurada PL / I (segunda ed.) . Nueva York: John Wiley and Sons. ISBN 0-471-01908-9.