Курсовая работа: Особливості мови програмування С
2.1.1.6 Арифметичні дії над вказівниками
Над вказівниками можна здійснювати ряд арифметичних дій. При цьому передбачається, що якщо вказівник p відноситься до типа T*, то p вказує на елемент деякого масиву типа T. Тоді р+1 є Вказівником на наступний елемент цього масиву, а р-1 - Вказівником на попередній елемент. Аналогічно визначаються вирази р+n, n+p і р-n, а також дії p++, p--, ++p, --p, p+=n, p-=n, де n - ціле число. Поважно відзначити, що арифметичні дії з вказівниками виконуються в одиницях того типа, до якого відноситься вказівник. Тобто р+n, перетворене до цілого типа, містить на sizeof(T)*n більше значення, чим р.
З рівності p+n==p1 виходить, що p1-p==n. Саме так вводиться оператор різниці двох вказівників: його значенням є ціле, рівне кількості елементів масиву від p до p1. Відзначимо, що це - єдиний випадок в мові, коли результат бінарного оператора з операндами одного типа належить до принципово іншого типу.
Сума двох вказівників не має сенсу і тому не визначена. Не визначені також арифметичні дії над вказівниками void*, що не типізуються.
Нарешті, всі вказівники, у тому числі і що не типізуються, можна порівнювати, використовуючи операторів відношення >, <, >=, <= ==, != [4].
2.1.1.7 Вказівники і масиви
Вказівники і масиви тісно взаємозв'язані. Ім'я масиву може бути неявно перетворене до константного вказівника на перший елемент цього масиву. Так &a[0] рівноцінно а. Взагалі, вірна формула
&а[n]== a+n
тобто адреса n-того елементу масиву є збільшений на n елементів вказівник на початок масиву. Розийменовуя ліву і праву частини, отримуємо основну формулу, що зв'язує масиви і вказівники:
а[n]== *(a+n)
Дана формула, не дивлячись на простоту, вимагає декількох пояснень. По-перше, компілятор будь-який запис вигляду а[n] інтерпретує як *(a+n). По-друге, формула (*) пояснює, чому в C++ масиви індексуються з нуля і чому немає контролю виходу за кордони діапазону. Нарешті, використовуючи (*), ми можемо записати наступний ланцюжок рівності:
а[n]== *(a+n) == *(n+a) == n[a]
Таким чином, елемент масиву а з індексом 2 можна позначити не лише як а, але і як 2[a]
Із зв'язку масивів і вказівників витікає спосіб передачі масивів у функції - за допомогою вказівника на перший елемент[5].
2.1.1.8 Масиви вказівників на масиви
Двовимірні масиви можна створювати також за допомогою масивів вказівників, ініціалізувавши їх елементи адресами одновимірних масивів. Наприклад:
int b0[4]={1,2,3,4},
b1[4]={5,6,7,8},
b2[4]={9,0,1,2};
int* а[3]={b0,b1,b2};
В цьому випадку вираження а[1][2] розшифровується як *(а[1]+2), що у свою чергу є *(b1+2), або b1[2]. Аналогічного ефекту можна добитися, ініціалізувавши масив а динамічними одновимірними масивами:
int* а[3];
for (int i=0; i<3; i++)
а[i]=new int[4];
Сам масив вказівників також можна створити в динамічній пам'яті. Він контролюватиметься покажчиком на типа int*, тобто змінній типа int**. В результаті ми отримаємо двовимірний динамічний масив, розмірності якого можна задавати при виділенні пам'яті в процесі роботи програми:
int **a,n,m;
n=3; m=4;
a=new int*[n];
for (int i=0; i<n; i++)