Арифметика указателя двумерного массива

0

Скажем, у меня есть int array: int arr[5][5] и предполагается управление памятью на языке C.

Я хочу получить доступ к определенному элементу массива, используя только арифметику указателей и разыменование.

Предположим, я хотел получить доступ к элементу в: arr[i][j]

Сначала я попробовал сначала напечатать несколько вещей, чтобы понять, как работают адреса. Я напечатал адрес arr, arr+1 и arr+2, а arr+5.

Это были результаты:

0x7fff58475b80
0x7fff58475b94
0x7fff58475ba8
0x7fff58475be4

Мне интересно, почему разница между каждым адресом составляет 14 (в шестнадцатеричном) или 20 (в десятичной системе).

Кроме того, когда вы создаете двухмерный массив в стеке, является указателем на массив указателей на блоки памяти, созданные? Вот как я предполагаю, что мы выделяем пространство для массива:

  1. Выделите указатель arr на стек.
  2. Указатель arr содержит адрес в исходное местоположение массива указателей.
  3. Этот массив указателей содержит начальное местоположение строки в 2-мерном массиве.

Это верно?

EDIT: Также предположим, что вы хотите получить доступ к arr [i] [j] посредством арифметики указателей. Как это будет сделано? Если массив распределен динамически, я думаю, вы можете сделать * (* (arr + i) +j). Я не уверен, как вы это делаете для статических распределений? Мое предположение - * (arr + ((row_size * (i)) +j)). Это верно?

  • 1
    arr - это массив из 5 элементов типа int[5] каждый. sizeof(int[5]) == 20
  • 0
    is a pointer to an array of pointers to memory blocks created? Нет. Создан плоский массив «блоков памяти», каждый из которых, в свою очередь, является массивом. Возможно, это прояснит ситуацию: int arr[5][5] совпадает с typedef int Block[5]; Block arr[5];
Показать ещё 1 комментарий
Теги:
arrays
pointers

4 ответа

3

Мне интересно, почему разница между каждым адресом составляет 14 (в шестнадцатеричном) или 20 (в десятичной системе).

Возможно, потому что в вашей системе размер int равен 4 а во внутреннем массиве 5 int.

Чтобы получить представление о макете, попробуйте следующий код:

int a[5][5];
int k = 0;
for (int i = 0; i < 5; i++)
    for (int j = 0; j < 5; j++)
        a[i][j] = ++k;
int* p = &a[0][0];
for (int n = 0; n < 25; n++, p++)
    printf("%d ", *p);

Выход

1 2 3 4 ... 25

В стандарте C++ есть примечание (в 8.3.4 Массивы [dcl.arrays]):

[Примечание. Из всего этого следует, что массивы в C++ сохраняются по строкам (последний индекс меняется быстрее), и первый индекс в объявлении помогает определить объем памяти, потребляемой массивом, но не играет никакой другой роли в индексе расчеты. -End note]

1

Array - это набор похожих элементов данных, хранящихся в смежной памяти.

int arr[5][5];

В этом объявлении будет выделено смежное расположение памяти для всех элементов. скажем, начальная память - 1000.

array  starting   array elements
       address
arr[0]--> 1000 --> arr[0][0] arr[0][1] ... arr[0][4]
arr[1]--> 1020 --> arr[1][0] arr[1][1] ... arr[1][4]
arr[2]--> 1040 --> arr[2][0] arr[2][1] ... arr[2][4]
arr[3]--> 1060 --> arr[3][0] arr[3][1] ... arr[3][4]
arr[4]--> 1080 --> arr[4][0] arr[4][1] ... arr[4][4]

I'm wondering why the difference between each of address is 14(in Hexadecimal) or 20 (in decimal).

Каждый массив имеет 5 целых чисел, sizeof(int) равен 4. Таким образом, для 5 целых чисел будет выделено 20 байт памяти. Из-за этого только вы получаете разницу между каждым адресом массива 20 байтов (в десятичном формате. В шестнадцатеричном виде это 14)


1. Allocate a pointer 'arr' on stack.

-No. Выделите указатель на указатель на целое число (arr) в стеке. Это int **arr;

2. The arr pointer holds the address to the starting location of an array of pointers.
3. That array of pointers contains the starting location of a row in the 2-D array.

Теперь это правильно! Но это динамическое распределение памяти не статично!

1

Линейный адрес местоположения [i, j] в матрице 2d вычисляется по формуле:

linear_position = i * (capacity of column 0) + j;

Адрес рассчитывается из линейной позиции, используя размер массива и используя начальный адрес массива:

cell_address = &array[0][0] + linear_position * sizeof(array[0][0]);

Включение ваших значений в приведенные выше уравнения должно дать вам указание на различия в адресах.

  • 0
    capacity of column Вы имели в виду емкость строки?
1

(1) Адрес памяти всех 5 * 5 элементов из arr [5] [5] is & arr [0] [0], & arr [0] [1]... & arr [0] [4], & arr [ 1] [0],... & arr [1] [4],... & arr [4] [4]. Все они расположены последовательно с разницей sizeof (int). В вашем os, sizeof (int) = 4.

(2) С точки зрения адреса, arr + 1 = & arr [1] [0], arr + 2 = & arr [2] [0]. Это просто другое представление. Первая форма указателя, более поздняя - форма массива.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню