陣列步長
外觀
陣列步長(stride of an array,也稱increment, pitch或step size)是程式設計時,相鄰陣列元素在主記憶體中的開始地址的距離,度量單位可以是位元組或者陣列元素個數。步長不可小於陣列元素的尺寸,但可以大於,表示有填充的位元組。
陣列步長如果等於陣列元素的尺寸,則陣列在主記憶體中是連續的。這可稱為單位步長(unit stride)。非單位步長適用於二維陣列或多維陣列,
非單位步長的存在理由
[編輯]填充
[編輯]許多程式語言允許數據結構對齊。例如:
struct A {
int a;
char b;
};
struct A myArray[100];
myArray
可能具有步長為8,而不是5。這用於最佳化處理時間而不是最佳化最少使用主記憶體。
平行陣列的重疊
[編輯]重疊的平行陣列:
#include <stdio.h>
struct MyRecord {
int value;
char *text;
};
/*
Print the contents of an array of ints with the given stride.
Note that size_t is the correct type, as int can overflow.
*/
void print_some_ints(const int *arr, int length, size_t stride)
{
int i;
printf("Address\t\tValue\n");
for (i=0; i < length; ++i) {
printf("%p\t%d\n", arr, arr[0]);
arr = (int *)((unsigned char *)arr + stride);
}
}
int main(void)
{
int ints[100] = {0};
struct MyRecord records[100] = {0};
print_some_ints(&ints[0], 100, sizeof ints[0]);
print_some_ints(&records[0].value, 100, sizeof records[0]);
return 0;
}
這是一種類型雙關。
陣列剖面
[編輯]某些程式語言如PL/I允許從陣列中選項某些列或行作為陣列剖面(array cross-section)。[1]:p.262 例如,對於二維陣列:
declare some_array (12,2)fixed;
只考慮第二列的一個匯出陣列可參照為
some_array(*,2)
非單位步長多維陣列例子
[編輯]非單位步長特別適用於圖像。這允許建立子圖像而不必複製像素。Java範例:
public class GrayscaleImage {
private final int width, height, widthStride;
/** Pixel data. Pixel in single row are always considered contiguous in this example. */
private final byte[] pixels;
/** Offset of the first pixel within pixels */
private final int offset;
/** Constructor for contiguous data */
public Image(int width, int height, byte[] pixels) {
this.width = width;
this.height = height;
this.pixels = pixels;
this.offset = 0;
this.widthStride = width;
}
/** Subsection constructor */
public Image(int width, int height, byte[] pixels, int offset, int widthStride) {
this.width = width;
this.height = height;
this.pixels = pixels;
this.offset = offset;
this.widthStride = widthStride;
}
/** Returns a subregion of this Image as a new Image. This and the new image share
the pixels, so changes to the returned image will be reflected in this image. */
public Image crop(int x1, int y1, int x2, int y2) {
return new Image(x2 - x1, y2 - y1, pixels, offset + y1*widthStride + x1, widthStride);
}
/** Returns pixel value at specified coordinate */
public byte getPixelAt(int x, int y) {
return pixels[offset + y * widthStride + x];
}
}
參考文獻
[編輯]- ^ Hughes, Joan K. PL/I Structured Programming (second ed.). New York: John Wiley and Sons. 1979. ISBN 0-471-01908-9.