- •Тема 13: Покажчики. Зв'язок покажчика з масивами. Динамічна пам'ять
- •1. Покажчики
- •У змінній p міститься випадкова адреса: 0xNnnnnnnn
- •Void main()
- •2. Способи ініціалізації покажчиків
- •Void main() {
- •Void main()
- •Void main()
- •3. Зв'язок покажчика з одновимірним масивом
- •Void main() {
- •4. Двовимірний масив
- •Void main()
- •5. Динамічна пам'ять
- •Void main()
- •Void main()
- •Void main()
- •Void main() {
Void main() {
int x[10], i, s = 0; // x – покажчик на перший елемент масиву.
int *rpt; // Визначаєм покажчик rpt і засилаємо туди значення
rpt = x; // адреси 1-го елементу масиву. У x і rpt зберігається адреса 1-го
// елементу. Значення в змінній x змінювати не МОЖНА!!!
clrscr();
cout << "Введи елементи масиву: \n ";
for (; rpt - x < n; rpt++)// В циклі формуємо поточну адресу
// елементу масиву.
{ i = rpt - x; // Якщо відоме значення покажчика, індекс елементу
// визначається формулою: i = rpt – x.
// rpt – поточне значення покажчика; x – адреса 1-го елементу.
cout << "x[" << i << "]= ";
scanf("%d", rpt);// Порівняєте з директивою scanf(%d”, &x[i]).
}
// Виведення масиву на екран.
for (rpt = x; rpt - x < n; rpt++ )
cout << *rpt << " ";// Доступ до елементу через покажчик.
for (i = 0; i < n; i++) s = s + *(x + i);// Інша форма доступу до елементу масиву
// через покажчик.
сout << "\n S= " << s << "\n";
getch(); }
Програма демонструє факт, що значення а, *(а + i) і *rpt (якщо код rpt++ виконується i разів) визначають одну і ту ж область пам'яті.
4. Двовимірний масив
Якщо задана матриця, наприклад а, те для неї визначений масив покажчиків а[n]. У i-м елементі масиву а[i] міститься адреса першого елементу i-й рядка. У змінній а міститься адреса першого елементу матриці, тобто справедлива тотожність &a[0][0] ? а.
Програма 9. Демонструє, що при оголошенні двовимірного масиву, визначений масив покажчиків на перші елементи рядків матриці.
const n = 5, m =4;
Void main()
{int b[n][m], i;
clrscr();
for (i = 0; i < n; i++) // Перебираємо індекси рядків //двовимірного масиву.
{ cout << " b(" << i << ")= " << b[i]; // Виведення значень //елементів одновимірного масиву.
// Виведення адрес перших елементів рядків матриці.
cout << " \n адреса b(" << i << ",0)= " << &b[i][0] << "\n\n";
} getch(); }
Дана програма демонструє той факт, що для змінної b[i] справедлива рівність b[i]= &b[i][0]. Зв'язок матриці з масивом покажчиків дозволяє організувати доступ до елементів матриці через адреси. Для елементу матриці а[i][j] справедливі наступні формули:
-
вираз а + i * m + j визначає адресу а, тобто &a[i][j] =a + i * m + j або а[i][j] = *(а + i * m + j). Тут i * m + j – порядковий номер елементу а[i][j];
-
вираз а[i]+ j визначає адресу а, тобто &a[i][j] = а[i]+j або а[i][j] = *( а[i]+ j).
Програма 10. Демонструє різні форми доступу до елементів матриці через покажчики.
void main(void)
{ const n = 4, m = 4;
FILE *f1;
int i,j *p, а[n][m];
clrscr();
// Введення двовимірного масиву з файлу.
p = а[0];
f1 = fopen("t.dat", "r");
cout << "Доступ до елементів матриці відбувається по формулі: \n\n"
<< "\n *(а[i]+ j) \n\n";
for (i = 0; i <= n – 1; i++)
{ for (j = 0; j <= m – 1; j++, p++)
{ fscanf( f1, "%d", p ); // Одна з форм доступу до елементів
// матриці через масив покажчиків.
printf(" %d\t", *(а[i]+ j)); // Одна з форм доступу до //елементів матриці через масив покажчиків.
}
printf("\n"); }
fclose(f1);
printf("\n");
p = а[0];
cout << "Доступ до елементів матриці відбувається по формулах: \n"
<< " *(а[i]+ j) \n *(p + i *m + j) \n\n";
f1 = fopen("t1.dat", "w");
for (i = 0; i <= n – 1; i++)
{ for (j = 0; j <= m – 1; j++)
{ printf(f1,"%d ", *(а[i]+ j ) ); // Одна з форм доступу до //елементів матриці через масив покажчиків.
printf(" %d\t", *(p + i * m + j )); // Одна з форм доступу до //елементів матриці через масив покажчиків. }
fprintf(f1,"\n");
printf("\n"); }
fclose(f1);
getch(); }