stringtranslate.com

Шаг массива

В программировании шаг массива (также называемый приращением , шагом или размером шага ) — это количество ячеек в памяти между началами последовательных элементов массива , измеряемое в байтах или в единицах размера элементов массива. Шаг не может быть меньше размера элемента, но может быть больше, указывая на дополнительное пространство между элементами.

Массив с шагом точно такого же размера, как и размер каждого из его элементов, является непрерывным в памяти. Иногда говорят, что такие массивы имеют единичный шаг . Массивы с единичным шагом иногда более эффективны, чем массивы с неединичным шагом, но массивы с неединичным шагом могут быть более эффективными для двумерных или многомерных массивов , в зависимости от эффектов кэширования и используемых шаблонов доступа [ необходима цитата ] . Это можно отнести к принципу локальности , в частности пространственной локальности .

Причины неединичного шага

Массивы могут иметь шаг, превышающий ширину их элементов в байтах, по крайней мере в двух случаях:

Перекрывающиеся параллельные массивы

Некоторые языки позволяют обрабатывать массивы структур как перекрывающиеся параллельные массивы с неединичным шагом:

#include <stdio.h> struct MyRecord { int value ; char * text ; };      /** Вывести содержимое массива целых чисел с заданным шагом.  Обратите внимание, что size_t — правильный тип, так как int может переполняться. */ void print_some_ints ( const int * arr , int length , size_t stride ) { int i ; printf ( "Адрес \t\t Значение \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 или Fortran, допускают так называемое поперечное сечение массива , которое выбирает определенные столбцы или строки из большего массива. [1] : стр.262  Например, если двумерный массив объявлен как

объявить  some_array  ( 12 , 2 ) фиксированным ;

массив одного измерения, состоящий только из второго столбца, может быть обозначен как

некоторый_массив ( * , 2 )

Пример многомерного массива с неединичным шагом

Неединичный шаг особенно полезен для изображений. Он позволяет создавать подизображения без копирования данных пикселей. Пример Java:

public class GrayscaleImage { private final int width , height , widthStride ; /** Данные пикселей. В этом примере пиксели в одной строке всегда считаются смежными. */ private final byte [] pixels ; /** Смещение первого пикселя в пикселях */ private final int offset ;                    /** Конструктор для смежных данных */ public Image ( int width , int height , byte [] pixels ) { this . width = width ; this . height = height ; this . pixels = pixels ; this . offset = 0 ; this . widthStride = width ; }                         /** Конструктор подраздела */ 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 ; }                             /** Возвращает подобласть этого изображения как новое изображение. Это и новое изображение разделяют  пиксели, поэтому изменения в возвращенном изображении будут отражены в этом изображении. */ public Image crop ( int x1 , int y1 , int x2 , int y2 ) { return new Image ( x2 - x1 , y2 - y1 , pixels , offset + y1 * widthStride + x1 , widthStride ); }                              /** Возвращает значение пикселя в указанной координате */ public byte getPixelAt ( int x , int y ) { return pixels [ offset + y * widthStride + x ] ; } }                

Ссылки

  1. ^ Хьюз, Джоан К (1979). PL/I Structured Programming (второе изд.) . Нью-Йорк: John Wiley and Sons. ISBN 0-471-01908-9.