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  ]  ;  }  }