Steg av en array
I datorprogrammering är stegen för en array (även kallad inkrement , pitch eller stegstorlek ) antalet platser i minnet mellan början av på varandra följande arrayelement , mätt i byte eller i enheter av storleken på arrayens element. Steget kan inte vara mindre än elementstorleken men kan vara större, vilket indikerar extra utrymme mellan elementen.
En array med steg av exakt samma storlek som storleken på vart och ett av dess element är sammanhängande i minnet. Sådana arrayer sägs ibland ha enhetssteg . Unit stride arrays är ibland mer effektiva än non-unit stride arrays, men non-unit stride arrays kan vara mer effektiva för 2D eller flerdimensionella arrayer, beroende på effekterna av caching och åtkomstmönstren som används [ citat behövs ] . Detta kan tillskrivas lokalitetsprincipen , närmare bestämt rumslig lokalitet .
Orsaker till icke-enhetssteg
Matriser kan ha ett steg större än deras elements bredd i byte i minst tre fall:
Stoppning
Många språk (inklusive C och C++ ) tillåter att strukturer utfylls för att bättre dra fördel av antingen ordlängden och/eller cache-radstorleken på maskinen. Till exempel:
struct A { int a ; char b ; }; struktur A myArray [ 100 ];
I ovanstående kodavsnitt kan myArray
mycket väl visa sig ha ett steg på åtta byte, snarare än fem (4 byte för int plus en för char), om C-koden kompilerades för en 32-bitars arkitektur , och kompilatorn hade optimerat (som vanligtvis är fallet) för minimal bearbetningstid snarare än minsta minnesanvändning.
Överlappande parallella arrayer
Vissa språk tillåter att arrayer av strukturer behandlas som överlappande parallella arrayer med icke-enhetssteg:
0
0
0
0
0 0
0 0
0
#include <stdio.h> struct MyRecord { int värde ; char * text ; }; /** Skriv ut innehållet i en rad ints med det givna steget. Observera att size_t är rätt typ, eftersom int kan svämma över. */ void print_some_ints ( const int * arr , int length , size_t stride ) { int i ; printf ( "Adress \t\t Värde \n " ); för ( i = ; i < längd ; ++ i ) { printf ( "%p \t %d \n " , arr , arr [ ]); arr = ( int * )(( osignerad char * ) arr + stride ); } } int main ( void ) { int ints [ 100 ] = { }; struct MyRecord records [ 100 ] = { }; print_some_ints ( & ints [ ], 100 , sizeof ints [ ]); print_some_ints ( & poster [ ]. värde , 100 , storlek på poster [ ]); återvända ; }
Detta idiom är en form av typpunning .
Array-tvärsnitt
Vissa språk som PL/I tillåter det som kallas ett array-tvärsnitt , som väljer vissa kolumner eller rader från en större array. Till exempel, om en tvådimensionell matris deklareras som
förklara some_array ( 12 , 2 ) fixad ;
en array av en dimension som endast består av den andra kolumnen kan hänvisas till
some_array ( * , 2 )
Exempel på flerdimensionell array med icke-enhetssteg
Skritt utan enhet är särskilt användbart för bilder. Det gör det möjligt att skapa underbilder utan att kopiera pixeldata. Java-exempel:
0
public class GrayscaleImage { private final int width , height , widthStride ; /** Pixeldata. Pixel i en rad anses alltid vara sammanhängande i det här exemplet. */ privat slutlig byte [] pixlar ; /** Offset av den första pixeln inom pixlar */ privat slutlig int offset ; /** Konstruktör för sammanhängande data */ offentlig bild ( int bredd , int höjd , byte [ ] pixlar ) { this . bredd = bredd ; detta . höjd = höjd ; detta . pixlar = pixlar ; detta . offset = ; detta . widthStride = width ; } /** Undersektionskonstruktor */ offentlig bild ( int width , int height , byte [] pixlar , int offset , int widthStride ) { this . bredd = bredd ; detta . höjd = höjd ; detta . pixlar = pixlar ; detta . offset = offset ; detta . widthStride = widthStride ; } /** Returnerar en underregion av denna bild som en ny bild. Denna och den nya bilden delar pixlarna, så ändringar av den returnerade bilden kommer att återspeglas i den här bilden. */ offentlig bildbeskärning ( int x1 , int y1 , int x2 , int y2 ) { returnera ny bild ( x2 - x1 , y2 - y1 , pixlar , offset + y1 * widthStride + x1 , widthStride ) ; } /** Returnerar pixelvärde vid specificerad koordinat */ public byte getPixelAt ( int x , int y ) { return pixels [ offset + y * widthStride + x ] ; } }