Указатели C · 3 min read · Nov 20, 2025
Учебник по программированию на C для Linux Часть 21: Указатели на символы, массив указателей и указатель на указатель

Концепция указателей действительно является одной из самых важных концепций в языке программирования C. До сих пор мы обсуждали несколько аспектов указателей в C. Расширяя эту тему, в этом учебнике мы обсудим еще несколько концепций указателей.
Указатели на символы, массив указателей и указатель на указатель в C
Давайте начнем с указателей на символы с помощью следующих строк кода:
char p[] = "Мне нравится HowtoForge"
char *p = "Мне нравится HowToForge"Первая строка определяет массив ‘p’ размером, равным количеству символов в двойных кавычках. Но следующая строка определяет указатель ‘p’, который указывает на строковую константу.
Разница здесь в том, что первый ‘p’, будучи массивом, вы можете легко изменить или изменить содержимое массива. Но поскольку второй ‘p’ указывает на строковую константу, вы просто не можете изменить содержимое строки.
Например, следующий фрагмент кода пытается изменить строковую константу:
#include
int main()
{
char *p = "Мне нравится HowToForge";
p[0] = 'U';
return 0;
} И вот вывод, который был получен этим кодом на моей системе:
Ошибка сегментацииЭта ошибка указывает на то, что выполнение программы завершилось неожиданно, и это произошло потому, что мы попытались изменить что-то, что является константой.
Также имейте в виду, что хотя указатель ‘p’ может быть перенаправлен на другую строку, вы не можете изменить базовый адрес массива ‘p’ (если вы помните, мы уже обсуждали это в одном из наших предыдущих учебников).
Теперь перейдем к массивам указателей, так же как вы видели массивы целых чисел, символов и других типов, может быть и массив указателей. Например, следующая программа определяет массив ‘arr’ указателей на целые числа и присваивает ему значения.
#include
int main()
{
int *arr[3];
int a = 0, b = 1, c = 2;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;
return 0;
} Обратите внимание, что значения, присвоенные массиву, являются адресами. Это потому, что ‘arr’ — это массив указателей, а указатели хранят только адреса. Теперь, если вы хотите получить доступ к значениям, хранящимся по этим адресам, вам придется использовать оператор *.
Следующий пример (который является просто расширением предыдущего примера) демонстрирует это:
#include
int main()
{
int *arr[3];
int a = 0, b = 1, c = 2;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;
for(int i=0; i < 3; i++)
printf("\n arr[%d] is: %d",i,*(arr[i]));
return 0;
} Вот вывод:
arr[0] is: 0
arr[1] is: 1
arr[2] is: 2 Аналогично массивам указателей на целые числа (как мы обсуждали здесь), вы можете иметь массивы, хранящие указатели на символы и другие.
Теперь давайте перейдем к указателю на указатели. Как мы уже много раз упоминали, указатель хранит адрес. Теперь, до сих пор в этой продолжающейся серии учебников по программированию на C, мы видели только указатель, указывающий на переменную, не являющуюся указателем, но на самом деле указатели могут указывать и на другие указатели.
Это означает, что указатель может хранить адрес другого указателя. Например, следующее — это двойной указатель или указатель на указатель:
int **ptr;Вот фрагмент кода, который использует двойной указатель:
#include
int main()
{
int *ptr;
int p;
int a = 10;
ptr = &a;
p = &ptr;
printf("\n Указатель 'p' указывает на указатель 'ptr', который далее указывает на значение: %d", p);
return 0;
} Вот вывод:
Указатель 'p' указывает на указатель 'ptr', который далее указывает на значение: 10Итак, это был пример двойного указателя. По аналогии, вы можете иметь указатель на указатель на указатель, определяемый, например, как int *ptr. Максимальное количество таких уровней ‘указатель на указатель на……’ зависит от реализации (в некоторых случаях предел составляет 12).
На практике, однако, вы, вероятно, столкнетесь только с указателями на указатели до уровня трех, так как наличие большего количества уровней делает логику более сложной для понимания и поддержки.
Заключение
Мы обсудили три важных концепции, связанные с указателями. Вам рекомендуется попробовать примеры и концепции, которые мы обсудили здесь, на вашей системе, чтобы лучше понять, как это работает. В случае любых сомнений или вопросов оставьте нам комментарий ниже.
Get new posts in your inbox
No spam. Unsubscribe anytime.