跳至內容

數組步長

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書

數組步長(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];
    }
  }

參考文獻

  1. ^ Hughes, Joan K. PL/I Structured Programming (second ed.). New York: John Wiley and Sons. 1979. ISBN 0-471-01908-9.