В этом руководстве вы узнаете об указателях; что такое указатели, как вы их используете и с какими типичными ошибками вы можете столкнуться при работе с ними с помощью примеров.
Указатели - мощные возможности программирования C и C ++. Прежде чем изучать указатели, давайте узнаем об адресах в программировании на C.
Адрес в C
Если у вас есть переменная var в вашей программе, &var
вы получите ее адрес в памяти.
Мы использовали адрес много раз при использовании scanf()
функции.
scanf("%d", &var);
Здесь значение, введенное пользователем, сохраняется в адресе переменной var. Возьмем рабочий пример.
#include int main() ( int var = 5; printf("var: %d", var); // Notice the use of & before var printf("address of var: %p", &var); return 0; )
Вывод
var: 5 адрес var: 2686778
Примечание: вы, вероятно, получите другой адрес, когда запустите приведенный выше код.
Указатели C
Указатели (переменные-указатели) - это специальные переменные, которые используются для хранения адресов, а не значений.
Синтаксис указателя
Вот как мы можем объявить указатели.
int* p;
Здесь мы объявили указатель p int
типа.
Вы также можете объявить указатели этими способами.
int *p1; int * p2;
Возьмем еще один пример объявления указателей.
int* p1, p2;
Здесь мы объявили указатель p1 и обычную переменную p2.
Назначение адресов указателям
Возьмем пример.
int* pc, c; c = 5; pc = &c;
Здесь 5 присвоено переменной c. И адрес c присваивается указателю pc.
Получите ценность вещи, указанную указателями
Чтобы получить значение объекта, на который указывают указатели, мы используем *
оператор. Например:
int* pc, c; c = 5; pc = &c; printf("%d", *pc); // Output: 5
Здесь адрес c
назначается указателю pc. Чтобы получить значение, хранящееся в этом адресе, мы использовали * pc.
Примечание. В приведенном выше примере pc - это указатель, а не *pc
. Вы не можете и не должны делать что-то подобное *pc = &c
;
Кстати, *
называется оператором разыменования (при работе с указателями). Он работает с указателем и выдает значение, хранящееся в этом указателе.
Изменение значения, указанного указателями
Возьмем пример.
int* pc, c; c = 5; pc = &c; c = 1; printf("%d", c); // Output: 1 printf("%d", *pc); // Ouptut: 1
Мы присвоили указателю pc адрес c.
Затем мы изменили значение c на 1. Поскольку pc и адрес c совпадают, *pc
мы получаем 1.
Возьмем другой пример.
int* pc, c; c = 5; pc = &c; *pc = 1; printf("%d", *pc); // Ouptut: 1 printf("%d", c); // Output: 1
Мы присвоили указателю pc адрес c.
Затем мы перешли *pc
на 1, используя *pc = 1;
. Поскольку pc и адрес c одинаковы, c будет равно 1.
Возьмем еще один пример.
int* pc, c, d; c = 5; d = -15; pc = &c; printf("%d", *pc); // Output: 5 pc = &d; printf("%d", *pc); // Ouptut: -15
Первоначально адрес c присваивается указателю pc с помощью pc = &c;
. Поскольку c равно 5, *pc
получаем 5.
Затем адрес d присваивается указателю pc с помощью pc = &d;
. Поскольку d равно -15, *pc
мы получаем -15.
Пример: работа указателей
Возьмем рабочий пример.
#include int main() ( int* pc, c; c = 22; printf("Address of c: %p", &c); printf("Value of c: %d", c); // 22 pc = &c; printf("Address of pointer pc: %p", pc); printf("Content of pointer pc: %d", *pc); // 22 c = 11; printf("Address of pointer pc: %p", pc); printf("Content of pointer pc: %d", *pc); // 11 *pc = 2; printf("Address of c: %p", &c); printf("Value of c: %d", c); // 2 return 0; )
Вывод
Адрес c: 2686784 Значение c: 22 Адрес указателя pc: 2686784 Содержимое указателя pc: 22 Адрес указателя pc: 2686784 Содержимое указателя pc: 11 Адрес c: 2686784 Значение c: 2
Пояснение к программе
int* pc, c;
Here, a pointer pc and a normal variable c, both of typeint
, is created.
Since pc and c are not initialized at initially, pointer pc points to either no address or a random address. And, variable c has an address but contains random garbage value.c = 22;
This assigns 22 to the variable c. That is, 22 is stored in the memory location of variable c.pc = &c;
This assigns the address of variable c to the pointer pc.c = 11;
This assigns 11 to variable c.*pc = 2;
This change the value at the memory location pointed by the pointer pc to 2.
Common mistakes when working with pointers
Suppose, you want pointer pc to point to the address of c. Then,
int c, *pc; // pc is address but c is not pc = c; // Error // &c is address but *pc is not *pc = &c; // Error // both &c and pc are addresses pc = &c; // both c and *pc values *pc = c;
Here's an example of pointer syntax beginners often find confusing.
#include int main() ( int c = 5; int *p = &c; printf("%d", *p); // 5 return 0; )
Why didn't we get an error when using int *p = &c;
?
It's because
int *p = &c;
is equivalent to
int *p: p = &c;
В обоих случаях мы создаем указатель p
(не *p
) и назначаем &c
ему.
Чтобы избежать этой путаницы, мы можем использовать такой оператор:
int* p = &c;
Теперь вы знаете, что такое указатели, и узнаете, как указатели связаны с массивами в следующем руководстве.