Покажчики в C: Що таке покажчик у програмуванні на C? Типи
Що таке покажчик у C?
Кнопка Покажчик у C, це змінна, яка зберігає адресу іншої змінної. Покажчик також можна використовувати для посилання на іншу функцію вказівника. Покажчик можна збільшувати/зменшувати, тобто вказувати на наступне/попереднє місце пам’яті. Мета вказівника - заощадити простір пам'яті та досягти швидшого часу виконання.
Як використовувати покажчики в C
Якщо ми оголосимо змінну v типу int, v фактично зберігатиме значення.
v тепер дорівнює нулю.
Однак кожна змінна, крім значення, має також свою адресу (або, простіше кажучи, місце її розташування в пам'яті). Адресу можна отримати, поставивши амперсанд (&) перед назвою змінної.
Якщо ви надрукуєте адресу змінної на екрані, вона буде виглядати як абсолютно випадкове число (більше того, воно може відрізнятися від циклу до циклу).
Давайте спробуємо це на практиці з покажчиком у прикладі C
Результатом цієї програми є -480613588.
Тепер, що таке покажчик? Замість того, щоб зберігати значення, покажчик зберігатиме адресу змінної.
Змінна покажчика
Int *y = &v;
ЗМІННИЙ | Вказівник |
---|---|
A значення зберігається в названий адресу зберігання/пам'яті | A змінна Що вказує на адресу зберігання/пам’яті інший змінна |
Оголошення покажчика
Як і змінні, покажчики в Програмування на C мають бути оголошені, перш ніж їх можна буде використовувати у вашій програмі. Покажчики можна називати як завгодно, якщо вони підкоряються правилам іменування C. Оголошення покажчика має такий вигляд.
data_type * pointer_variable_name;
Тут,
- тип даних є базовим типом покажчика серед типів змінних C і вказує тип змінної, на яку вказує покажчик.
- Зірочка (*: та сама зірочка, що використовується для множення), яка є оператором непрямості, оголошує покажчик.
Давайте подивимося на деякі дійсні оголошення покажчиків у цьому підручнику з покажчиків C:
int *ptr_thing; /* pointer to an integer */ int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */ double *ptr2; /* pointer to a double */ float *ptr3; /* pointer to a float */ char *ch1 ; /* pointer to a character */ float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */
Ініціалізація покажчика
Після оголошення покажчика ми ініціалізуємо його як стандартні змінні за допомогою адреси змінної. Якщо покажчики в програмуванні на C неініціалізовані та використовуються в програмі, результати можуть бути непередбачуваними та потенційно катастрофічними.
Щоб отримати адресу змінної, ми використовуємо оператор амперсанд (&), який ставиться перед назвою змінної, адреса якої нам потрібна. Ініціалізація покажчика виконується за допомогою наступного синтаксису.
Синтаксис покажчика
pointer = &variable;
Проста програма для ілюстрації вказівника наведена нижче:
#include <stdio.h> int main() { int a=10; //variable declaration int *p; //pointer variable declaration p=&a; //store address of variable a in pointer p printf("Address stored in a variable p is:%x\n",p); //accessing the address printf("Value stored in a variable p is:%d\n",*p); //accessing the value return 0; }
вихід:
Address stored in a variable p is:60ff08 Value stored in a variable p is:10
Operaтор | Сенс |
---|---|
* | Служить 2 цілям
|
& | Служить лише для 1 призначення
|
Типи покажчиків у C
Нижче наведено різні Типи покажчиків у C:
Нульовий покажчик
Ми можемо створити нульовий покажчик, присвоївши нульове значення під час оголошення покажчика. Цей метод корисний, коли вказівнику не призначено адреси. Нульовий покажчик завжди містить значення 0.
Наступна програма ілюструє використання нульового покажчика:
#include <stdio.h> int main() { int *p = NULL; //null pointer printf(“The value inside variable p is:\n%x”,p); return 0; }
вихід:
The value inside variable p is: 0
Покажчик пустоти
In Програмування на C, вказівник на недійсність також називається загальним вказівником. Він не має жодного стандартного типу даних. Покажчик void створюється за допомогою ключового слова void. Його можна використовувати для зберігання адреси будь-якої змінної.
Наступна програма ілюструє використання вказівника на недійсність:
#include <stdio.h> int main() { void *p = NULL; //void pointer printf("The size of pointer is:%d\n",sizeof(p)); return 0; }
вихід:
The size of pointer is:4
Дикий пойнтер
Вказівник називається диким вказівником, якщо він нічого не ініціалізується. Ці типи покажчиків C неефективні, оскільки вони можуть вказувати на деяку невідому область пам’яті, що може спричинити проблеми в нашій програмі та призвести до збою програми. Працюючи з дикими покажчиками, завжди потрібно бути обережним.
Наступна програма ілюструє використання дикого покажчика:
#include <stdio.h> int main() { int *p; //wild pointer printf("\n%d",*p); return 0; }
вихід:
timeout: the monitored command dumped core sh: line 1: 95298 Segmentation fault timeout 10s main
Інші типи покажчиків у 'c':
- Висячий покажчик
- Складний покажчик
- Поруч вказівник
- Далекий покажчик
- Величезний покажчик
Покажчики прямого та непрямого доступу
У C є два еквівалентні способи доступу до змінного вмісту та керування ним
- Прямий доступ: ми використовуємо безпосередньо назву змінної
- Непрямий доступ: ми використовуємо покажчик на змінну
Давайте розберемося в цьому за допомогою наведеної нижче програми
#include <stdio.h> /* Declare and initialize an int variable */ int var = 1; /* Declare a pointer to int */ int *ptr; int main( void ) { /* Initialize ptr to point to var */ ptr = &var; /* Access var directly and indirectly */ printf("\nDirect access, var = %d", var); printf("\nIndirect access, var = %d", *ptr); /* Display the address of var two ways */ printf("\n\nThe address of var = %d", &var); printf("\nThe address of var = %d\n", ptr); /*change the content of var through the pointer*/ *ptr=48; printf("\nIndirect access, var = %d", *ptr); return 0;}
Після компіляції програми без будь-яких помилок результат:
Direct access, var = 1 Indirect access, var = 1 The address of var = 4202496 The address of var = 4202496 Indirect access, var = 48
Арифметика вказівника в C
Операції з покажчиками підсумовано на наступному малюнку
Пріоритетна операція (прецедент)
Працюючи з покажчиками C, ми повинні дотримуватися наступних правил пріоритету:
- Оператори * та & мають той самий пріоритет, що й унарні оператори (заперечення!, приріст++, декремент–).
- У цьому ж виразі унарні оператори *, &,!, ++, – обчислюються справа наліво.
Якщо вказівник P вказує на змінну X, тоді * P можна використовувати всюди, де можна записати X.
Наступні вирази еквівалентні:
int X =10 int *P = &Y; For the above code, below expressions are true
вираз | Еквівалентний вираз |
---|---|
Y=*P+1
*P=*P+10 *P+=2 +++П (*P)++ |
Y=X+1
X=X+10 X+=2 ++X X++ |
В останньому випадку потрібні дужки: оскільки унарні оператори * та ++ обчислюються справа наліво, без дужок буде збільшено вказівник P, а не об’єкт, на який вказує P.
У таблиці нижче показано арифметичні та основні операції, які можна використовувати під час роботи з покажчиками C
Operaції | Пояснення |
---|---|
Призначення | int *P1,*P2 P1=P2; P1 і P2 вказують на одну цілу змінну |
Інкрементація та декрементація | Int *P1; P1++;P1– ; |
Додавання зсуву (константа) | Це дозволяє вказівнику переміщувати N елементів у таблиці. Покажчик буде збільшено або зменшено в N разів на кількість байтів типу змінної. P1+5; |
Покажчики та масиви C із прикладами
Традиційно ми отримуємо доступ до елементів масиву, використовуючи його індекс, але цей метод можна усунути за допомогою покажчиків. Покажчики полегшують доступ до кожного елемента масиву.
#include <stdio.h> int main() { int a[5]={1,2,3,4,5}; //array initialization int *p; //pointer declaration /*the ptr points to the first element of the array*/ p=a; /*We can also type simply ptr==&a[0] */ printf("Printing the array elements using pointer\n"); for(int i=0;i<5;i++) //loop for traversing array elements { printf("\n%x",*p); //printing array elements p++; //incrementing to the next element, you can also write p=p+1 } return 0; }
вихід:
1 2 3 4 5
Додавання певного числа до вказівника перемістить розташування вказівника до значення, отриманого операцією додавання. Припустимо, що p є вказівником, який на даний момент вказує на комірку пам’яті 0, якщо ми виконаємо наступну операцію додавання, p+1, тоді вона виконається таким чином:
Оскільки p на даний момент вказує на розташування 0 після додавання 1, значення стане 1, і, отже, вказівник вказуватиме на розташування пам’яті 1.
C Покажчики та рядки з прикладами
Рядок — це масив об’єктів char, що закінчується нульовим символом '\ 0'. Ми можемо маніпулювати рядками за допомогою вказівників. Цей покажчик у прикладі C пояснює цей розділ
#include <stdio.h> #include <string.h> int main() { char str[]="Hello Guru99!"; char *p; p=str; printf("First character is:%c\n",*p); p =p+1; printf("Next character is:%c\n",*p); printf("Printing all the characters in a string\n"); p=str; //reset the pointer for(int i=0;i<strlen(str);i++) { printf("%c\n",*p); p++; } return 0; }
вихід:
First character is:H Next character is:e Printing all the characters in a string H e l l o G u r u 9 9 !
Інший спосіб роботи з рядками — масив покажчиків, як у наступній програмі:
#include <stdio.h> int main(){ char *materials[ ] = { "iron", "copper", "gold"}; printf("Please remember these materials :\n"); int i ; for (i = 0; i < 3; i++) { printf("%s\n", materials[ i ]);} return 0;}
вихід:
Please remember these materials: iron copper gold
Переваги покажчиків у C
- Покажчики корисні для доступу до ділянок пам'яті.
- Покажчики забезпечують ефективний спосіб доступу до елементів структури масиву.
- Покажчики використовуються для динамічного розподілу пам'яті, а також для звільнення.
- Покажчики використовуються для формування складних структур даних, таких як зв’язаний список, графік, дерево тощо.
Недоліки покажчиків у C
- Покажчики трохи складні для розуміння.
- Покажчики можуть призвести до різноманітних помилок, таких як помилки сегментації, або можуть отримати доступ до місця пам’яті, яке взагалі не потрібно.
- Якщо покажчику надано неправильне значення, це може спричинити пошкодження пам’яті.
- Покажчики також відповідають за витік пам'яті.
- Покажчики порівняно повільніші, ніж у змінних.
- Програмістам дуже важко працювати з покажчиками; тому програміст зобов'язаний обережно працювати з вказівником.
Підсумки
- Покажчик - це не що інше, як область пам'яті, де зберігаються дані.
- Для доступу до місця пам'яті використовується покажчик.
- Існують різні типи вказівників, наприклад нульовий вказівник, дикий вказівник, вказівник на пусті та інші типи вказівників.
- Покажчики можна використовувати з масивами та рядками для більш ефективного доступу до елементів.
- Ми можемо створити покажчики на функції для динамічного виклику функції.
- З покажчиком можна виконувати арифметичні операції, які називаються арифметикою вказівника.
- Покажчики також можуть вказувати на функцію, що полегшує виклик різних функцій у разі визначення масиву покажчиків.
- Якщо ви хочете працювати з різними змінними типами даних, ви можете використовувати вказівник типу void.