Учебник по программированию на C для Linux, часть 19: указатели и массивы
На этой странице
- Указатели и массивы
- Заключение
До сих пор в этой продолжающейся серии руководств по программированию на C мы кратко обсуждали основы указателей. Однако есть еще несколько концепций, связанных с указателями, которые необходимо обсудить. Итак, в этом уроке мы обсудим концепцию указателей и массивов.
Прежде чем мы начнем с указателей и массивов, давайте быстро освежим базовую концепцию самих указателей. Указатели — это особый тип переменных, которые могут содержать адреса. Например, указатель ptr на символ может быть объявлен следующим образом;
char *ptr;
И вы можете использовать знак амперсанда, чтобы сохранить в нем адрес. Вот пример:
char c = 'a';
ptr = &c;
Итак, теперь указатель ptr содержит адрес переменной c. В качестве альтернативы вы также можете сказать, что ptr теперь указывает на переменную c.
Чтобы получить доступ или управлять значением переменной, на которую указывает указатель, вы можете использовать оператор *. Например, чтобы изменить значение переменной c с a на b, вы можете использовать указатель ptr следующим образом:
*ptr = 'b';
Следующая программа должна дать вам лучшее представление об этих основных концепциях указателей, которые мы обсуждали до сих пор:
#include <stdio.h>
int main()
{
char c = 'a';
char *ptr = &c;
*ptr = 'b';
printf ("variable c = %c", c);
return 0;
}
Вот вывод этой программы:
variable c = b
Таким образом, вы можете видеть, используя указатель, значение переменной было изменено.
Указатели и массивы
По мере того, как вы будете тратить все больше и больше времени на написание и чтение кода C, вы заметите, что указатели и массивы часто используются вместе. Например, вы можете получить доступ к отдельным элементам массива с помощью указателя. Рассмотрим следующий фрагмент кода:
...
...
...
char arr[] = {'a','b','c','d','e'}
char *ptr;
ptr = &arr[0]
...
...
...
Здесь указатель ptr указывает на первый элемент массива arr, который, если говорить с точки зрения индексов, находится в нулевой позиции массива. Теперь вы можете использовать оператор * с ptr для доступа/манипулирования значением, на которое указывает указатель.
Двигаясь дальше, когда у вас есть указатель, указывающий на первый элемент массива, легко получить доступ и к другим элементам массива. Например, если — в контексте фрагмента кода выше — вы везде используете следующее выражение:
*(ptr+1)
затем он позволяет вам получить доступ ко второму элементу массива, что вы обычно используете следующим образом:
arr[1]
Таким образом, добавление 1 к ptr приводит к адресу следующего элемента в массиве, и с помощью * вы можете получить доступ к значению, хранящемуся по этому адресу. Точно так же добавление 2 приводит к третьему элементу... и так далее, и тому подобное.
Вот программа, которая должна дать вам более четкое представление о том, что мы только что обсуждали:
#include <stdio.h>
int main()
{
char arr[] = {'a','b','c','d','e'};
char *ptr = &arr[0];
for(int i=0;i<strlen(arr);i++)
printf ("arr[%d] is %c \n", i, *(ptr+i));
return 0;
}
И вот вывод:
arr[0] is a
arr[1] is b
arr[2] is c
arr[3] is d
arr[4] is e
Итак, вы можете видеть, что выражение *(ptr+i) — где i варьируется от 0 до последнего индекса в массиве — позволяет нам получить доступ ко всем элементам массива.
ПРИМЕЧАНИЕ 1. Имя массива, используемое в коде, дает вам базовый адрес массива. Это означает, что имя массива и адрес его первого элемента — одно и то же. Таким образом, в контексте массива arr, &arr[0] и arr — это одно и то же. Это распространяется и на другие элементы, то есть &arr[2] также можно записать как (arr+2) и так далее.
ПРИМЕЧАНИЕ 2. Расширяя то, что мы обсуждали в примечании выше, каждое представление элемента массива можно разбить на представление указателя. Например: arr[2] эквивалентно *(arr + 2).
ПРИМЕЧАНИЕ 3. Хотя вы можете присвоить адрес массива указателю, наоборот недопустимо. Кроме того, в отличие от указателей, вы не можете использовать операторы ++ или -- с именем массива. Вообще говоря, вы не можете изменить адреса, по которым изначально расположены элементы массива.
Заключение
В этом руководстве основное внимание уделяется концепции указателей и массивов, их взаимосвязи и доступу к элементам массива с помощью указателей. Ближе к концу мы также обсудили некоторые важные моменты, связанные с кодом, использующим указатели на массивы.
Попробуйте эти концепции локально на своем компьютере, чтобы лучше понять, как они работают, и в случае каких-либо сомнений или вопросов оставьте комментарий ниже.