Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4246

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Глава 5. Указатели и массивы 

71 

Но: 

  const int n = 2; 
  int *p = NULL;    /* p – указатель на переменную */ 
  p = &n;  /* ошибка, так как p – указатель на переменную */ 

Указатель  на  константу  запрещает  косвенное  изменение  этой 
константы. Например: 

  const int n = 2; 
  const int *p = &n;  /* p – указатель на константу */ 
  (*p)++;  /* ошибка, так как p – указатель на константу */ 

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

  int n = 2; 
  const int *p = &n;  /* p – указатель на константу */ 
  p = &n;  /* правильно */ 

Значение константного указателя изменять нельзя. Например: 

  int n = 2; 
  int* const p = &n;  /* p – константный указатель */ 
  (*p)++;  /* правильно, n = 3 */ 
  p++;     /* ошибка, так как p – константа */ 

Теперь  объявим  константный  указатель  на  константу.  В  этом 
случае нельзя изменить как значение такого указателя, так и зна-
чение константы, на которую он ссылается. Например: 

  const int n = 2; 
  const int* const p =&n; /* конст. указатель на константу */ 
  (*p)++;  /* ошибка, так как n – константа */ 
  p++;     /* ошибка, так как p – константа */ 

5.5. Одномерные массивы 

Массив

 —  это  последовательность  данных  одного  типа,  которые 

хранятся в непрерывной области памяти друг за другом. Единица 
данных  массива  называется 

элементом

  массива.  Доступ  к  эле-

ментам массива производится по их номерам в последовательно-


background image

Часть I. Язык программирования С 

72 

сти, которые называются 

индексами

. Одномерный массив объяв-

ляется следующим образом: 

  спецификатор_типа идентификатор[диапазон]; 

Здесь 

спецификатор_типа

 определяет тип элементов массива, 

иден-

тификатор

  задает  имя  массива,  а 

диапазон

 —  количество  элемен-

тов в массиве. При этом имя массива является константным ука-
зателем на его первый элемент, а 

диапазон

 должен быть задан по-

ложительным  целочисленным  литералом  или  именованной 
константой. Например: 

  int  a[10];  /* массив из десяти целых чисел */ 

При объявлении массива его можно явно инициализировать, пе-
речислив значения элементов массива в фигурных скобках в по-
рядке возрастания индекса. Например: 

  char s[3] = {'a', 'b', 'c'}; 
  int a[3] = {0, 1, 2}; 

При инициализации массива возможны три ситуации: 

 

размер  массива  равен  количеству  значений  в  списке  инициа-
лизации; 

 

размер массива больше количества значений в списке инициа-
лизации; 

 

размер массива меньше количества значений в списке инициа-
лизации. 

В  первом  случае  происходит  обычная  инициализация  элементов 
массива. Во втором случае оставшиеся неинициализированными 
элементы  массива  инициализируются  нулями.  В  третьем  случае 
компилятор выдаст сообщение об ошибке. 
Если  значения  элементов  массива  перечисляются  явно,  то  раз-
мерность массива можно не указывать. В этом случае компилятор 
сам определит размерность по количеству элементов. Например: 

  int a[] = {0, 1, 2};  /* массив из трех элементов */ 

Доступ к элементам массива выполняется при помощи 

операто-

ра индексирования

, который имеет следующий вид: 

  имя_массива[индекс] 


background image

Глава 5. Указатели и массивы 

73 

Возвращает  оператор  индексирования  L-value.  При  этом  выход 
индекса  за  пределы  допустимого  диапазона  не  проверяется.  На-
пример: 

  int a[3] = {0, 1, 2}; 
  int n; 
  n = a[0]; 
  a[0] = 10; 

Особенно отметим, что нумерация элементов массива начинается 
с нуля. Приоритет оператора индексирования превышает приори-
тет унарных арифметических и побитовых операторов и совпада-
ет  с  приоритетом  постфиксных  операций  инкремента  и  декре-
мента. 
Так как верхний предел индекса массива может использоваться в 
программе многократно, то его лучше определить как именован-
ную  константу.  В  этом  случае  легче  вносить  изменения  в  про-
грамму при изменении размерности массива. Например: 

  const int n = 10; 
  int a[n];  /* массив из десяти целых чисел */ 

В  связи  с  этим  возникает  вопрос,  какой  модификатор  знака  вы-
брать для типа индекса массива 

unsigned

 или 

signed

. Так как ин-

дексы  это  неотрицательные  целые  числа,  то  можно  предполо-
жить, что лучше использовать модификатор знака 

unsigned

. Но на 

практике  для  индекса  обычно  выбирают  модификатор  знака 

signed

,  т. к.  в  этом  случае  легче  находить  ошибки,  связанные  с 

неправильным изменением значения индекса. 
Так  как  имя  массива  фактически  представляет  собой  указатель, 
то оператор индексирования может применяться к любым указа-
телям. Отсюда следует, что имя массива может также быть опе-
рандом оператора разыменования. 
В  языке  программирования  С++  имя  массива  имеет  следующий 
тип: 

  спецификатор_типа[диапазон] 

Однако этот тип неявно приводится к типу указателя на 

специфи-

катор_типа


background image

Часть I. Язык программирования С 

74 

5.6. Строки 

Строкой

  называется  массив  символов,  который  заканчивается 

пустым  символом 

\0

.  Для  инициализации  строки  используются 

строковые  литералы.  Если  длина  массива  больше  чем  длина 
строкового  литерала,  то  оставшиеся  свободными  байты  инициа-
лизируются нулями. Например: 

  char s[10] = "string"; 

Если длина строки должна быть равна длине строкового литера-
ла,  то  размерность  массива  лучше  не  указывать,  ее  подсчитает 
сам компилятор. Например: 

  char s[] = "string"; 

Пустую строку можно объявить следующим образом: 

  char s[10] = ""; 

В языке программирования C для работы со строками существует 
большое количество функций, прототипы которых описаны в за-
головочном  файле  и  string.h.  Работа  с  этими  функциями  будет 
рассмотрена в 

гл. 29

5.7. Арифметические действия 
с указателями 

Над указателями одного типа можно выполнять арифметическую 
операцию  вычитания 

-

.  Результатом  этой  операции  будет  целое 

число, которое указывает, на сколько один адрес памяти смещен 
относительно  другого  в  единицах,  равных  длине  базового  типа 
данных указателей. Например: 

  int a[5]; 
  int n, m; 
  n = &a[5] - &a[3];  /* n = 2  */ 
  m = &a[3] - &a[5];  /* m = -2 */ 

К указателю можно прибавить или вычесть целое число. В этом 
случае  значение  указателя  соответственно  увеличится  или 


background image

Глава 5. Указатели и массивы 

75 

уменьшится  на  это  число,  умноженное  на  длину  базового  типа 
данных указателя. Например: 

  int a[5]; 
  int *p = a+2;  /* p = &a[2] */ 

К  указателю  можно  применять  операции 

++

  и 

--

.  В  этом  случае 

значение  указателя  соответственно  увеличится  или  уменьшится 
на длину базового типа данных указателя. Например: 

  double* p; 
  ++p; 

5.8. Многомерные массивы 

Массив, элементы которого нумеруются несколькими индексами, 
называется 

многомерным

.  Компилятор  должен  поддерживать 

многомерные массивы, элементы которых нумеруются, по край-
ней  мере,  12  индексами.  Объявляется  многомерный  массив  сле-
дующим образом: 

  спецификатор_типа идентификатор[диапазон_1]...[диапазон_n]; 

Тип многомерного массива определяется следующим образом: 

  спецификатор_типа(*)[диапазон_2]...[диапазон_n] 

Причина такой типизации заключается в том, что при объявлении 
многомерного  массива  память  резервируется  под  все  элементы 
массива сразу, а сами элементы массива располагаются по стро-
кам.  Такое  решение  было  принято  для  увеличения  производи-
тельности  программы  при  работе  с  многомерными  массивами. 
Например, двумерный целочисленный массив может быть объяв-
лен как: 

  int arr[2][2]; 

В этом случае 

arr

 является именованной константой, тип которой 

равен 

int(*)[2]

При инициализации многомерного массива его элементы заклю-
чаются в фигурные скобки. Например: 

  int a[2][2] = {1, 1, 2, 2}; 


Смотрите также файлы