Константы и указатели


Отдельно стоит сказать про указатели на константы и константные указатели.

Кроме переменных в программе на Си для хранения данных могут использоваться константы, которые предваряются ключевым словом const, и указатели также могут указывать на константы, но в этом случае перед определением указателя также ставится слово const:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(void)
{
const int a = 10;
const int *pa = &a;
printf("address=%p \t value=%d \n", pa, *pa);

return 0;
}
Здесь указатель pa указывает на константу a. Поэтому даже если мы захотим изменить значение по адресу, который хранится в указателе, мы не сможем это сделать, например так:

1
*pa = 34;
В этом случае мы просто получим ошибку во время компиляции.

Возможна также ситуация, когда указатель на константу на самом деле указывает на переменную:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main(void)
{
int a = 10;
const int *pa = &a;
printf("value=%d \n", *pa); // 10
a = 22;
printf("value=%d \n", *pa); // 22
//*pa = 34; // так делать нельзя

return 0;
}
В этом случае переменную отдельно мы сможем изменять, однако по прежнему изменить ее значение через указатель мы не сможем.

Через указатель на константу мы не можем изменять значение переменной/константы. Но мы можем присвоить указателю адрес любой другой переменной или константы:

1
2
3
4
int a = 10;
const int *pa = &a; // указатель указывает на переменную a
const int b = 45;
pa = &b; // указатель указывает на константу b
Но также мы можем определять константные указатели. Они не могут изменять адрес, который в них хранится, но могут изменять значение по этому адресу.

1
2
3
4
5
6
7
8
int a = 10;
int *const pa = &a;
printf("value=%d \n", *pa); // 10
*pa = 22; // меняем значение
printf("value=%d \n", *pa); // 22

int b = 45;
// pa = &b; так нельзя сделать
И объединение обоих предыдущих случаев - константный указатель на константу, который не позволяет менять ни хранимый в нем адрес, ни значение по этому адресу:

1
2
3
4
5
6
7
int a = 10;
const int *const pa = &a;

//*pa = 22; так сделать нельзя

int b = 45;
// pa = &b; так сделать нельзя