Поиск по сайту:

Учебник по программированию на C для Linux, часть 19: указатели и массивы


На этой странице

  1. Указатели и массивы
  2. Заключение

До сих пор в этой продолжающейся серии руководств по программированию на 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. Хотя вы можете присвоить адрес массива указателю, наоборот недопустимо. Кроме того, в отличие от указателей, вы не можете использовать операторы ++ или -- с именем массива. Вообще говоря, вы не можете изменить адреса, по которым изначально расположены элементы массива.

Заключение

В этом руководстве основное внимание уделяется концепции указателей и массивов, их взаимосвязи и доступу к элементам массива с помощью указателей. Ближе к концу мы также обсудили некоторые важные моменты, связанные с кодом, использующим указатели на массивы.

Попробуйте эти концепции локально на своем компьютере, чтобы лучше понять, как они работают, и в случае каких-либо сомнений или вопросов оставьте комментарий ниже.