Покажчик на масив | Покажчик масиву

Покажчик на масив | Покажчик масиву

Необхідна умова: Покажчики Вступ

Розглянемо таку програму:

C




#include> int> main()> {> > int> arr[5] = { 1, 2, 3, 4, 5 };> > int> *ptr = arr;> > printf> (> '%p '> , ptr);> > return> 0;> }>

У наведеній вище програмі ми маємо покажчик птр що вказує на 0 тис елемент масиву. Так само ми можемо оголосити вказівник, який може вказувати на весь масив, а не лише на один елемент масиву. Цей покажчик корисний, коли йдеться про багатовимірні масиви.

Синтаксис:

data_type  (* var_name ) [size_of_array]; 

Тут:

    data_type — це тип даних, які містить масив. var_name — це ім'я змінної покажчика. size_of_array — це розмір масиву, на який буде вказувати вказівник.

приклад

int (*ptr)[10]; 

тут птр це покажчик, який може вказувати на масив з 10 цілих чисел. Оскільки нижній індекс має вищий пріоритет, ніж непрямість, необхідно взяти оператор непрямості та ім’я вказівника в круглі дужки. Тут тип ptr є «вказівником на масив з 10 цілих чисел.

Примітка: покажчик, який вказує на 0 тис елемент масиву та покажчик, який вказує на весь масив, абсолютно різні. Наступна програма показує це:

C




// C program to understand difference between> // pointer to an integer and pointer to an> // array of integers.> #include> int> main()> {> > // Pointer to an integer> > int> *p;> > > // Pointer to an array of 5 integers> > int> (*ptr)[5];> > int> arr[5];> > > // Points to 0th element of the arr.> > p = arr;> > > // Points to the whole array arr.> > ptr = &arr;> > > printf> (> 'p = %p, ptr = %p '> , p, ptr);> > > p++;> > ptr++;> > > printf> (> 'p = %p, ptr = %p '> , p, ptr);> > > return> 0;> }>

Вихід

p = 0x7fff6463e890, ptr = 0x7fff6463e890 p = 0x7fff6463e894, ptr = 0x7fff6463e8a4 

тут, стор є вказівником на 0 тис елемент масиву обр , поки птр це покажчик, який вказує на весь масив обр .

  • Базовий тип стор є базовим типом int while птр це «масив із 5 цілих чисел».
  • Ми знаємо, що арифметика вказівника виконується відносно базового розміру, тому, якщо ми пишемо ptr++, тоді вказівник птр буде зміщено вперед на 20 байт.

На наступному малюнку показано покажчик p і ptr. Темніша стрілка позначає вказівник на масив.

Після розіменування виразу покажчика ми отримуємо значення, на яке вказує цей вираз покажчика. Покажчик на масив вказує на масив, тому, розіменувавши його, ми повинні отримати масив, а ім’я масиву позначає базову адресу. Отже, коли вказівник на масив розіменовується, ми отримуємо базову адресу масиву, на який він вказує.

C




// C program to illustrate sizes of> // pointer of array> #include> int> main()> {> > int> arr[] = { 3, 5, 6, 7, 9 };> > int> *p = arr;> > int> (*ptr)[5] = &arr;> > > printf> (> 'p = %p, ptr = %p '> , p, ptr);> > printf> (> '*p = %d, *ptr = %p '> , *p, *ptr);> > > printf> (> 'sizeof(p) = %lu, sizeof(*p) = %lu '> ,> > sizeof> (p),> sizeof> (*p));> > printf> (> 'sizeof(ptr) = %lu, sizeof(*ptr) = %lu '> ,> > sizeof> (ptr),> sizeof> (*ptr));> > return> 0;> }>

Вихід

p = 0x7fff55adbff0, ptr = 0x7fff55adbff0 *p = 3, *ptr = 0x7fff55adbff0 sizeof(p) = 8, sizeof(*p) = 4 sizeof(ptr) = 8, sizeof(*ptr) = 20 

Покажчик на багатовимірні масиви

1. Покажчики та двовимірні масиви

У двовимірному масиві ми можемо отримати доступ до кожного елемента за допомогою двох нижніх індексів, де перший нижній індекс представляє номер рядка, а другий нижній індекс представляє номер стовпця. До елементів двовимірного масиву також можна отримати доступ за допомогою вказівної нотації. Припустимо, arr є двовимірним масивом, ми можемо отримати доступ до будь-якого елемента arr[i][j] масиву за допомогою виразу покажчика *(*(arr + i) + j) . Тепер ми побачимо, як можна отримати цей вираз.
Візьмемо двовимірний масив обр[3][4] :

int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; 

Оскільки пам'ять комп'ютера організована лінійно, неможливо зберігати двовимірний масив у рядках і стовпцях. Концепція рядків і стовпців є лише теоретичною; насправді двовимірний масив зберігається в порядку старших рядків, тобто рядки розміщуються поруч. На наступному малюнку показано, як наведений вище 2-D масив буде зберігатися в пам’яті.

Кожен рядок можна розглядати як одновимірний масив, тому двовимірний масив можна розглядати як набір одновимірних масивів, які розміщені один за одним. Іншими словами, ми можемо сказати, що це двовимірні масиви, які розміщені один за одним. Отже, тут обр це масив із 3 елементів, де кожен елемент є одновимірним масивом із 4 цілих чисел.
Ми знаємо, що ім’я масиву є постійним покажчиком, який вказує на 0 тис 1-D масив і містить адресу 5000. Оскільки обр є «вказівником на масив із 4 цілих чисел», відповідно до арифметики вказівників вираз arr + 1 представлятиме адресу 5016, а вираз arr + 2 представлятиме адресу 5032.
Тож ми можемо це сказати обр вказує на 0 тис 1-D масив, прибуток + 1 вказує на 1 вул 1-D масив і прибуток + 2 вказує на 2 nd 1-D масив.

Загалом можна написати:

 arr + i Points to ith element of arr ->Вказує на i-й одновимірний масив 
  • Оскільки arr + i вказує на i тис елемент обр , після розіменування він отримає i тис елемент обр який, звичайно, є 1-D масивом. Таким чином вираз *(arr + i) дає нам базову адресу i тис 1-D масив.
  • Ми знаємо, вказівний вираз *(arr + i) еквівалентний нижньому індексу arr[i] . Так *(arr + i) що те саме, що arr[i] дає нам базову адресу i тис 1-D масив.
  • Щоб отримати доступ до окремого елемента нашого 2-D масиву, ми повинні мати доступ до будь-якого j тис елемент i тис 1-D масив.
  • Оскільки базовий тип *(arr + i) є внутр і містить адресу 0 тис елемент i тис 1-D масив, ми можемо отримати адреси наступних елементів у i тис 1-D масив шляхом додавання цілих значень *(arr + i) .
  • Наприклад *(arr + i) + 1 представлятиме адресу 1 вул елемент 1 вул елемент i тис 1-D масив і *(arr+i)+2 представлятиме адресу 2 nd елемент i тис 1-D масив.
  • Так само *(arr + i) + j представлятиме адресу j тис елемент i тис 1-D масив. Розіменувавши цей вираз, ми можемо отримати j тис елемент i тис 1-D масив.

Покажчики та тривимірні масиви

int arr[2][3][2] = { {{5, 10}, {6, 11}, {7, 12}}, {{20, 30}, {21, 31}, {22, 32}} }; 

У тривимірному масиві ми можемо отримати доступ до кожного елемента за допомогою трьох індексів. Візьмемо тривимірний масив. Ми можемо розглядати тривимірний масив як масив двовимірного масиву, тобто кожен елемент тривимірного масиву вважається двовимірним масивом. Тривимірний масив обр можна розглядати як масив, що складається з двох елементів, де кожен елемент є двовимірним масивом. Ім'я масиву обр є вказівником на 0 тис 2-D масив.

Таким чином вираз покажчика *(*(*(arr + i ) + j ) + k) еквівалентно нижньому індексу arr[i][j][k].
Ми знаємо, що вираз *(arr + i) еквівалентний arr[i], а вираз *(*(arr + i) + j) еквівалентний arr[i][j]. Отже, ми можемо сказати, що arr[i] представляє базову адресу i тис 2-D масив і arr[i][j] представляє базову адресу j тис 1-D масив.

приклад

Наведений нижче приклад демонструє програму для друку елементів тривимірного масиву за допомогою вказівників.

C




// C program to print the elements of 3-D> // array using pointer notation> #include> int> main()> {> > int> arr[2][3][2] = {> > {> > {5, 10},> > {6, 11},> > {7, 12},> > },> > {> > {20, 30},> > {21, 31},> > {22, 32},> > }> > };> > int> i, j, k;> > for> (i = 0; i <2; i++)> > {> > for> (j = 0; j <3; j++)> > {> > for> (k = 0; k <2; k++)> > printf> (> '%d '> , *(*(*(arr + i) + j) +k));> > printf> (> ' '> );> > }> > }> > return> 0;> }>

Вихід

5 10 6 11 7 12 20 30 21 31 22 32 

На наступному малюнку показано, як тривимірний масив, який використовується у наведеній вище програмі, зберігається в пам’яті.

Підписка покажчика на масив

Припустимо обр це двовимірний масив із 3 рядками та 4 стовпцями птр є вказівником на масив із 4 цілих чисел, і птр містить базову адресу масиву обр .

int arr[3][4] = {{10, 11, 12, 13}, {20, 21, 22, 23}, {30, 31, 32, 33}}; int (*ptr)[4]; ptr = arr; 

Оскільки птр є покажчиком на перший рядок 2-D масиву, тобто масиву з 4 цілих чисел, ptr + i буде вказувати на i тис рядок. Про розіменування ptr + i , ми отримуємо базову адресу i тис рядок. Щоб отримати доступ до адреси j тис елемент i тис ми можемо додати j до виразу покажчика *(ptr + i) . Отже, вираз покажчика *(ptr + i) + j дає адресу j тис елемент i тис рядок і вираз покажчика *(*(ptr + i)+j) дає значення j тис елемент i тис рядок.
Ми знаємо, що вказівний вираз *(*(ptr + i) + j) еквівалентний індексовому виразу ptr[i][j]. Отже, якщо у нас є змінна-вказівник, що містить базову адресу двовимірного масиву, ми можемо отримати доступ до елементів масиву, подвійно підписавши цю змінну-вказівник.

приклад

C




// C program to print elements of a 2-D array> // by scripting a pointer to an array> #include> int> main()> {> > int> arr[3][4] = {> > {10, 11, 12, 13},> > {20, 21, 22, 23},> > {30, 31, 32, 33}> > };> > int> (*ptr)[4];> > ptr = arr;> > printf> (> '%p %p %p '> , ptr, ptr + 1, ptr + 2);> > printf> (> '%p %p %p '> , *ptr, *(ptr + 1), *(ptr + 2));> > printf> (> '%d %d %d '> , **ptr, *(*(ptr + 1) + 2), *(*(ptr + 2) + 3));> > printf> (> '%d %d %d '> , ptr[0][0], ptr[1][2], ptr[2][3]);> > return> 0;> }>

Вихід

0x7ffc9556b790 0x7ffc9556b7a0 0x7ffc9556b7b0 0x7ffc9556b790 0x7ffc9556b7a0 0x7ffc9556b7b0 10 22 33 10 22 33