Проектування програм з використанням покажчиків

Сайт: Навчально-інформаційний портал НУБіП України
Курс: Програмування (КН). Ч2 ☑️
Книга: Проектування програм з використанням покажчиків
Надруковано: Гість-користувач
Дата: четвер, 9 квітня 2026, 18:59

1. Зв'язок покажчиків з масивами

Масив є групою комірок пам'яті, які мають одне і те ж саме ім'я та однаковий тип. Для використання конкретної комірки або елемента масиву вказується ім'я масиву та зміщення цієї комірки відносно першої комірки або початку масиву. Зміщення вказується після імені масиву у квадратних дужках і називається індексом масиву.   

Ім'я масиву можна розглядати як покажчик-константу, значення якого є адресою масиву (що збігається з адресою першого елементу масиву). Наприклад, для отримання адреси масиву

int Array[9];

 можна записати такий оператор

printf (“%p”, &Array[0]);

або такий оператор

printf(“%p”,Array);

Якщо об’явити покажчик та присвоїти йому значення адреси першого елемента масиву, то такий покажчик фактично стає новою назвою такого масиву. Іншими словами, якщо об’явимо покажчик на цілий тип і виконаємо зазначене присвоєння, а саме

int *ptrArray=NULL;// int *ptrArray;

ptrArray=&Array[0];

то для присвоєння кожному елементу масиву Array значення, яке користувач введе на клавіатурі, необхідно написати такий оператор циклу:


for (i=0; i<9; i++) {

printf (“\nArray[%d]=”,i);

scanf(“%d”, &ptrArray[i]);

}


#include <stdio.h>

int main()

{

int Array[10],i;

int *ptrArray;

int N=4;

ptrArray=NULL;

ptrArray=&Array[0];

printf("Input array\n");

for (i=0; i<N; i++) {

printf ("\nArray[%d]=",i);

scanf("%d", &ptrArray[i]);

}


 printf("\nOutput array\n");

 for (i=0; i<N; i++) {

printf ("\nArray[%d]=%d  ",i,Array[i]);

}

ptrArray=&Array[0];

printf("\nOutput array with pointer\n");

 for (i=0; i<N; i++) {

printf ("\nArray[%d]=%d  ",i,*(ptrArray+i));

}

return 0;

}


2. Об'ява та ініціалізація змінної-покажчика

Покажчики є змінними, значення яких є адресами пам'яті.
Покажчик містить адресу змінної, в якій знаходиться певне значення. Змінна безпосередньо посилається на своє значення, покажчик посилається на значення певної змінної посередньо (непрямо). Посилання на значення за допомогою покажчика називається непрямим адресуванням.

Покажчики, як і інші змінні,  повинні бути об'явлені до моменту їхнього використання.

int *countPtr, count;

де countPtr типу int *    - покажчик на значення цілого типу;

змінна count цілого типу.

Можна об'являти покажчики, що посилаються на змінні будь-якого типа


•Покажчики повинні бути ініційовані або в момент об'яви, або за допомогою операції присвоєння.
•Покажчик може бути ініційований нулем, макросом NULL, значенням адреси.
•Покажчик із значенням NULL не посилається ні на що.
• Ініціація покажчика числом 0 еквівалентна ініціації покажчика константою NULL.
•Для уникнення непередбачених результатів покажчики повинні завжди бути ініційовані до моменту їхнього використання.

сhar c;   // змінна

char *p; // покажчик
p = &c;  // p = адреса c







3. Операції над покажчиками

Операція визначення адреси &  - це  унарна операція, яка повертає адресу свого операнд.

int х=16;

int *хPtr;

то наступний оператор

хPtr=&х;

присвоїть змінній-покажчику хPtr адресу змінної х.


Операція * називається непрямим адресуванням – це операція, що повертає значення об'єкта, на який посилається операнд (тобто покажчик).
Приклад:

printf(“%d”, *хPtr);

Виведе значення змінної х, тобто 16


Непряме адресування покажчика, який не був до цього моменту ініційований або якому не присвоїли значення, призведе до фатальної помилки під час виконання програми та непередбачених результатів щодо використання пам'яті

#include <stdio.h>

#include <conio.h>

main()

{

int a;

int *aPtr;

a=7;

aPtr=&a;

printf(“Адреса змінної а = %p\n Значення aPtr = %p \n\n”, &a, aPtr);

printf(“Значення змінної а = %d\n Значення *aPtr = %d \n\n”, a, *aPtr);

printf(“Перевіримо роботу операцій * i &.\n &*аPtr = %p\n*&aPtr = %p \n\n”, &*aPtr, *&aPtr);

return 0;

}

#include <stdio.h>

#include <conio.h>

main()

{

int a;

int *aPtr;

a=7;

aPtr=&a;

printf(“variable adress а = %p\n value aPtr = %p \n\n”, &a, aPtr);

printf(“value variable а = %d\n value *aPtr = %d \n\n”, a, *aPtr);

printf(“Check the operation *  and  &.\n &*аPtr = %p\n*&aPtr = %p \n\n”, &*aPtr, *&aPtr);

getch();

return 0;

}




4. Вирази та арифметичні операції з покажчиками

До покажчиків може застосовуватися такий список арифметичних операцій:

•інкремент,
• декремент,
• додавання цілого числа (+ або +=),
• віднімання цілого числа (– або –=),
•обчислення різниці двох покажчиків.

Є одновимірний масив

int Arr[10];

Нехай перший елемент цього масиву буде мати в пам'яті адресу 3240.

Далі визначимо покажчик та ініціюємо його значення значенням першого елементу масиву:

int *vPtr=&Arr[0];

або

int *vPrt=Arr;

Якщо додати до покажчика або відняти із покажчика ціле число, значення покажчика збільшиться або зменшиться на добуток цього числа з розміром об'єкта, на який посилається покажчик.
vPtr+=2; дає в результаті 3244 (якщо вважати, що для цілого числа резервується 2 байти) і тепер покажчик vPtr посилається на другий елемент масиву Arr[2]

До покажчиків можна застосовувати операцію присвоєння, якщо обидва покажчики мають один і той же тип.
В іншому випадку треба використовувати операцію приведення типів у правій частині операції присвоєння.  Виключенням є тип void.
Покажчик будь-якого типу може бути присвоєний покажчику на void, і void-покажчик може бути присвоєний покажчику будь-якого типу.

Покажчики можуть порівнюватися один з одним.
При порівнянні покажчиків порівнюються адреси, які є значеннями цих покажчиків. Порівняння двох покажчиків, які посилаються на елементи одного масиву, можуть показати, наприклад, що один покажчик посилається на елемент із більшим значенням індексу  порівняно з іншим.
Інша операція порівняння покажчиків – це перевірка на рівність покажчика значенню NULL.


5. Покажчики і функції

void main()

{    int **ptr;

  int k,n,i,j;

  printf("\ninput row  ");

  scanf("%d",&k);

  printf("\ninput column  ");

  scanf("%d",&n);

  ptr=(int**) malloc (k*sizeof(int*));

  for(i=0;i<k;i++) ptr[i]=(int*) malloc (n*sizeof(int));

  input(k,n,ptr);

  output(k,n,ptr);

 printf("\nRezult:\n");

work(k,n,ptr);

 free(ptr);

  getch();

}

Приклад. Зчитати елементи одновимірного масиву з клавіатури, вивести на екран,

вивести елементи на непарних місцях

 #include <stdio.h>

 #include <stdlib.h>

 input(int si,float *A)

 {int ix;

    for (ix = 0; ix < si; ix++)

  {  printf ("\nInput element: ");

   scanf("%f",A+ix);

  }

 }

  output(int si,float *A)

 {int ix;

    for (ix = 0; ix < si; ix++)

  {  printf ("%.2f  ",*(A+ix));

  }

 }



int main()

{

  int size, ix;

  float *arrayPtr;

 printf("\n Input number of elements: ");

  scanf("%d",&size);

  arrayPtr=(float*)calloc(size,sizeof(float));

   if (arrayPtr == NULL) return 1;

  input(size,arrayPtr);

  output(size,arrayPtr);

  printf("\n");

  for (ix = 0; ix < size; ix++)

  {  if(ix%2!=0)

   printf("%.2f       ",*(arrayPtr+ix));

  } free(arrayPtr);

  return 0;}





Приклад 2. 

Зчитати елементи двовимірного масиву з клавіатури, вивести на екран,

Вивести парні елементи  в кожному рядку на екран



#include <stdio.h>

#include <conio.h>

void work(int k,int n,int **ptr);

void input(int r,int t,int **pp)

{

  int i,j;

for(i=0;i<r;i++)

  for(j=0;j<t;j++)

   scanf("%d",&pp[i][j]);

}



void output(int r,int t,int **pp)

{

  int i,j;

for(i=0;i<r;i++){

  for(j=0;j<t;j++)

   printf("%3d",pp[i][j]);

   printf("\n");

}

}


void work(int k,int n,int **ptr)

{

    int i,j;

    for (i=0;i<k;i++){

        for(j=0;j<n;j++)

    {

        if(ptr[i][j]%2==0) printf("%4d",ptr[i][j]);

    }

    printf("\n");

}

}






6. Робота з покажчиками (Відео)


Доступність

Шрифти Шрифти

Розмір шрифта Розмір шрифта

1

Колір тексту Колір тексту

Колір тла Колір тла

Кернінг шрифтів Кернінг шрифтів

Видимість картинок Видимість картинок

Інтервал між літерами Інтервал між літерами

0

Висота рядка Висота рядка

1.2

Виділити посилання Виділити посилання

Вирівнювання тексту Вирівнювання тексту

Ширина абзацу Ширина абзацу

0