Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вказівники та посилання.docx
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
857.42 Кб
Скачать

Void function_a (char*, int, short*);

Нижче наведено приклади деяких можливих оголошень вказівників:

Int *pi; /* вказівник-змінна на дані типу int */

float *pf; /* вказівник-змінна на дані типу float */

Зверніть увагу на те, що у трьох з наведених оголошень ім'я масиву є константою-вказівником!

3. Ініціалізація вказівника

Подібно до звичайної змінної перед першим використанням вказівник потребує ініціалізації.

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

Ініціалізація вказівника адресою може бути здійснена як безпосередньо при його оголошенні (див. загальний синтаксис) так і в процесі виконання програми (пізня ініціалізація):

int i=3;

int *j=&i; //рання ініціалізація

int *j;

j=&i; //пізня ініціалізація

Способи ініціалізації вказівника:

1) Присвоювання вказівнику адреси існуючого об'єкта:

а) за допомогою операції одержання адреси

int x=7; //ціла змінна x

int *px=&x // у вказівник заноситься адреса змінної x

Знак амперсанд (&) слід розуміти як адресу конкретної області пам'яті, для вказівника на змінну цей знак означає, що буде одержана саме адреса змінної у пам'яті, а не значення самої змінної. Таким чином, у цьому прикладі, у px зберігається адреса змінної x, тому px тепер вказує на x.

Тепер, якщо потрібно звернутися за адресою змінної x, можна використовувати px. Для такого звертання слід написати *px. Кажуть, що оператор (*) розіменовує вказівник.

б) за допомогою значення іншого (ініціалізованого) вказівника

int *z=px;

в) за допомогою імені масиву або функції (вони трактуються як адреса).

int y[20]; //масив y

int *py=y; //у вказівник py заноситься адреса початку масиву y.

2) Присвоювання адреси області пам'яті в явному вигляді.

int* v=(int*)0x800000;

3) Присвоювання порожнього значення.

int *s=NULL;

4. Розіменування та присвоєння

Як тільки оголошено вказівник j, можливий доступ до даних за адресою, що міститься в j, шляхом операції розіменування вказівника (операції доступу до значення, яке знаходиться в пам'яті за адресою на яку посилається вказівник)

Приклад 1

#include <stdio.h> // Потокове введення-виведення

#include <windows.h>

int main()

{

int i=3;

int *j=&i;

printf ("%d\n",i); // i = 3

*j=2; // змінити значення на яке посилається вказівник

printf ("%d\n",i); // i = 2

system("pause");

}

Скомпілюйте наведений приклад.

Приклад 2

#include <stdio.h> // Потокове введення-виведення

#include <windows.h>

int main()

{

int i=3;

float *j=&i;

printf ("%d\n",i); // i = 3

*j=2; // змінити значення на яке посилається вказівник

printf ("%d\n",i); // i = 2

system("pause");

}

Скомпілюйте наведений приклад.

Таким способом ми розглянули дві основні операції, які можна проводити з вказівниками: розіменування та присвоєння.

5. Void-вказівник

Поняття типу вказівника не існує, а існує лише поняття типу даних, на які посилається вказівник. Такі вказівники називають типованими. Якщо вказівник посилається на будь-який тип, то говорять про безтиповий або void-вказівник (void *i).

Void-вказівники забезпечують доступ до даних будь-якого типу. Для void-вказівників не підтримуються арифметичні операції, оскільки розмір не вказаний.

Для того щоб використовувати даний вказівник необхідно привести його до вказівника на тип даних відмінний від void.

Типований вказівник може бути присвоений безтиповому,

Приклад 3

#include <stdio.h>

#include <windows.h>

void main()

{

int *i;

void *z;

int j=5;

char c[]="aaaaa";

i=&j;

z=i;

z=&j;

z=&c;

system("pause");

}

Скомпілюйте наведений приклад.

але зворотнє присвоєння є хибним:

Приклад 4

#include <stdio.h>

#include <windows.h>

void main()

{

int *i;

void *z;

int j=5;

char c[]="aaaaa";

z=&j;

i=z;

z=&j;

z=&c;

system("pause");

}

Скомпілюйте наведений приклад.