Найти в Дзене

Массивы и строки

Оглавление

В этой статье будет рассказано:

  • Что такое массив
  • Объявление массива
  • Как данные хранятся в массиве
  • Доступ к данным
  • Изменение хранимых в массиве данных
  • Многомерные массивы
  • Объявление многомерного массива
  • Доступ к элементам в многомерном массиве
  • Строки в стиле C
  • Строки C++
  • Использование string

Что такое массив

Определение слова массив в словаре довольно близко к тому, что мы хотим понять. Согласно словарю Вебстера, массив — это “группа элементов, формирующих полный набор, например массив солнечных панелей”. Ниже приведены характеристики массива.

  • Массив — это коллекция элементов.
  • Все содержащиеся в массиве элементы имеют одинаковый вид.
  • Такая коллекция формирует полный набор.

В языке C++ массивы позволяют сохранить в памяти элементы данных одинакового типа в последовательном порядке.

Необходимость в массивах

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

int FirstNumber = 0;
int SecondNumber = 0;
int ThirdNumber = 0;
int FourthNumber = 0;
int FifthNumber = 0;

Если бы пользователю понадобилось хранить и впоследствии отображать 500 и более целых чисел, то пришлось бы объявить 500 таких целочисленных переменных, используя приведенную выше систему. Это потребует огромной работы и терпения на ее выполнение. А что делать, если пользователь попросить обеспечить 500.000 целых чисел вместо 5?

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

int MyNumbers [5] = {0};

Таким образом, если бы вас попросили обеспечить 500.000 целых чисел, то ваш массив без проблем увеличился бы так:

int MyNumbers [500000] = {0};

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

char MyCharacters [5];

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

Объявление и инициализация статических массивов

В приведенных выше строках кода я объявил массив MyNumbers, который содержит пять элементов типа int, инициализированных значением 0. Таким образом, для объявления массива в языке C++ используется следующий синтаксис:

тип_элемента имя_массива [количество_элементов] = {необязательные исходные данные}

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

int MyNumbers [5] = {34, 56, -21, 5002, 365};

Все элементы массива можно также инициализировать одним значением;

Int MyNumbers [5] = {100};

Вы можете также инициализировать только часть элементов массива:

int MyNumbers [5] = {34, 56}; // инициализировать первые два элемента

Вы можете определить длину массива (количество элементов в нем) как константу и использовать ее при определении массива:

const int ARRAY_LINGTH = 5;
int MyNumbers [ARRAY_LENGTH] = {34, 56, -21, 5002, 365};

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

ПРИМЕЧАНИЕ - При частичной инициализации массивов некоторые компиляторы инициализируют проигнорированные вами элементы исходным значением 0

Если исходное количество элементов в массиве неизвестно, можно не указывать его:

int MyNumbers [] = {2011, 2052, -525};

Приведенный выше код создает массив из трех целых чисел с исходными значения 2011,2052 и -525.

ПРИМЕЧАНИЕ - Массивы, которые мы объявили до сих пор, называются статическими массивами, поскольку их длина фиксируется программистом во время компиляции. Такой массив не может принять больше данных, чем определил программист. Он также не может задействовать меньше памяти, если используется только наполовину или вообще не используется.

Как данные хранятся в массиве

Рассмотрим книги, стоящие рядом на полке. Это пример одномерного массива, поскольку он располагается только в одной размерности, которой является количество книг в ней. Каждая книга - это элемент массива, а полка сродни области памяти, которая была зарезервирована для хранения этой коллекции книг.

Это не ошибка, мы начинаем нумеровать книги с нуля. Поскольку, как вы увидите позже, индексы в языке C++ начинаются с 0, а не с 1. Подобно пяти книгам на полке, массив MyNumbers, содержащий пять целых чисел, выглядит очень похоже на рисунке выше

-2

Обратите внимание, что занятая массивом область памяти состоит из пяти блоков равного размера, определяемого типом хранимых массивом данных, в данном случае типом int. Объем памяти, зарезервированной компилятором для массива MyNumbers, составит sizeof(int) * 5. В общем виде объем памяти в байтах, резервируемой компилятором для массива, составляет:

Байты массива = sizeof(тип элемента) * количество_элементов

Доступ к данным, хранимым в массиве

Для обращения к элементам массива можно использовать отсчитываемый от нуля индекс. Индексы называются отсчитываемыми от нуля потому, что первый элемент массива имеет индекс 0. Так, первое целочисленное значение, хранимое в массива MyNumbers, - это MyNumbers[0], второе - MyNumbers[1] и т.д. Пятый элемент - MyNumbers[4]. Другими словами, индекс последнего элемента в массиве на единицу меньше его длины.

Когда запрашивается доступ к элементу по индексу N, компилятор использует адрес области памяти первого элемента ( позиция нулевого индекса) как отправную точку, а затем пропускает N элементов, добавляя к нему смещение, вычисленное как N*sizeof(тип_элемента), чтобы получить адрес области, содержащей N+1-й элемент. Компилятор C++ не проверяет, находится ли индекс в пределах фактически определенных элементов массива. Вы можете попытаться выбрать элемент по индексу 1001 в массиве, содержащем только 10 элементов, поставив под угрозу безопасность и стабильность вашей программы. Ответственность за предотвращение к элементам за пределами массива лежит исключительно на программисте.

Внимание! Результат доступа к массиву за его пределами непредсказуем. Как правило, это нарушает работу программы. Этого нужно избегать любой ценой.

Программа ниже демонстрирует объявление массива целых чисел, инициализацию его элементов целочисленными значениями и обращение к ним для отображения на экране.

*знак решетки*include <iostream>
using namespace std;
int main ()
{
int MyNumbers [5] = {34, 56, -21, 5002, 365};
cout « "Первый элемент с индексом 0: " « MyNumbers [0] « endl;
cout « "Второй элемент с индексом 1: " « MyNumbers [1] « endl;
cout « "Третий элемент в индексе 2: " « MyNumbers [2] « endl;
cout « "Четвертый элемент в индексе 3: " « MyNumbers [3] « endl;
cout « "Пятый элемент в индексе 4: " « MyNumbers [4] « endl;
return 0;
}

Результат

Первый элемент с индексом 0: 34
Второй элемент с индексом 1: 56
Третий элемент в индексе 2: -21
Четвертый элемент в индексе 3: 5002
Пятый элемент в индексе 4: 365

В строке 6 объявляется массив из пяти целых чисел с исходными значениями, определенными для каждого из них. Последующие строки просто отображают целые числа, используя оператор cout и переменную типа массива MyNumbers с соответствующим индексом.

Изменение хранимых в массиве данных

В коде предыдущей программы пользовательские данных не вводились в массив. Синтаксис присвоения целого числа элементу в этом массиве очень похож на присвоение значения целочисленной переменной.

Например, присвоение значения 2011 целочисленной переменной выглядит так:

int AnlntegerValue;
AnlntegerValue = 2011;

Присвоение значения 2011 четвертому элементу в рассматриваемом массиве выглядит так:

MyNumbers [3] = 2011; // Присвоение 2011 четвертому элементу

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

*знак решетки* include <iostream>
using namespace std;
int main()
{
const int ARRAY_LENGTH = 5;
//Массив из 5 целых чисел, инициализированных нулями
int MyNumbers [ARRAY_LENGTH] = {0};
cout << "Введите индекс элемента, который будет изменен: ";
int nElementIndex = 0;
cin >> nElementIndex;
cout << "Введите новое значение: ";
cin >> MyNumbers [nElementIndex];
cout « "Первый элемент с индексом 0: " « MyNumbers [0] « endl;
cout « "Второй элемент с индексом 1: " « MyNumbers [1] « endl;
cout « "Третий элемент в индексе 2: " « MyNumbers [2] « endl;
cout « "Четвертый элемент в индексе 3: " « MyNumbers [3] « endl;
cout « "Пятый элемент в индексе 4: " « MyNumbers [4] « endl;
return 0;
}

Результат

Введите индекс элемента, который будет изменен: 2
Введите новое значение: 2011
Первый элемент с индексом 0: 0
Второй элемент с индексом 1: 0
Третий элемент в индексе 2: 2011
Четвертый элемент в индексе 3: 0
Пятый элемент в индексе 4: 0


Синтаксис объявления массива в строке 8 использует константу const integer ARRAY_LENGTH, инициализированную предварительно значением пять. Поскольку это статический массив, его длина фиксируется во время компиляции. Компилятор заменяет константу ARRAY_LENGTH значением 5 и компилирует код, полагая, что MyArray - это целочисленный массив, содержащий пять элементов. В строке 10-12 пользователя спрашивают, какой элемент массива он хочет изменить, а введенный индекс сохранятся в целочисленной переменной ElementIndex. Это значение используется в строке 14 для изменения содержимого массива. Вывод демонстрируется, что изменился элемент по индексу 2, фактически это был третий элемент массива, поскольку индексы отсчитываются от нуля. Вы должны привыкнуть к этому.

ПРИМЕЧАНИЕ - Многие новички в программировании на языке C++ присваивают значение пятому элементу массива из пяти целых чисел по индексу пять. Обратите внимание: это уже за пределами массива, и откопилированный код попытается обратиться к шестому элементу массива, состоящему из пяти элементов.

ВНИМАНИЕ! - Во второй программе отсутствует нечто фундаментальное: проверка введенного пользователем индекса на соответствие границам массива. Фактически предыдущая программа должна проверять, находится ли значение переменной nElenemtIndex в пределах от 0 до 4, и отбрасывать все остальные значения. Отсутствие этой проверки позволяет пользователю присвоить значение вне границ массива. Потенциально это может привести к нарушению работы приложения, а в самом плохом случае и ОС.

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

Массивы, которые мы рассматривали до сих пор, напоминали книги на полке. Может быть больше книг на более длинной полке или меньше на более короткой. Таким образом, длина полки - единственная размерность, определяющая ее емкость, следовательно, она одномерна. Но что если теперь нужно использовать массив для моделирования солнечных панелей, как показано на рисунке ниже? Солнечные панели, в отличие от книжных полок, распространяются в двух размерностях: по длине и по ширине.

-3

Как можно заметить на рисунке, шесть солнечных панелей располагаются в двумерном порядке: два ряда по три столбца. С одной стороны вы можете рассматривать такое расположение как массив из двух элементов, каждый из которых сам является массивом их трех панелей, другими словами, как массив массивов. В языке C++ вы можете создавать двумерные массивы, но вы не ограничены только двумя размерностями. В зависимости от необходимости и характера приложения вы можете также создать в памяти многомерные массивы.

Объявление и инициализация многомерных массивов

Язык C++ позволяет объявлять многомерные массивы, указав количество элементов, которое необходимо зарезервировать по каждой размерности. Следовательно, двумерный массив целых чисел, представляющий солнечные панели, можно объявить так:

int SolarPanellDs [2][3];

Обратите внимание, что на рисунке каждой из шести присвоен также идентификатор в пределах от 0 до 5. Если бы пришлось инициализировать целочисленный массив в том же порядке, то это выглядело бы так:

int SolarPanellDs [2][3] = {{0, 1, 2}, {3, 4, 5}};

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

int ThreeRowsThreeColumns [3][3] = {{-501, 206, 2011}, {989, 101, 206}, {303, 456, 596}};

ПРИМЕЧАНИЕ - Даже при том, что язык C++ позволяет использовать модель многомерных массивов, в памяти массив содержится как одномерный. Компилятор раскладывает многомерный массив в области памяти, которая расширяется только в одно направлении.
Если инициализировать тот же массив SolarPanelIDs следующим образом, то результат был бы тем же:
int SolarPanellDs [2] [3] = {0, 1, 2, 3, 4, 5};
Однако предыдущий способ наглядней, поскольку так проще представить и понять, что многомерный массив - это массив массивов.

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

Считайте многомерный массив массивом массивов. Поскольку рассмотренный ранее двумерный массив включал три ряда и три столбца, содержащих целые числа, вы можете представить его как массив, состоящий из трех элементов, каждый из которых является массивом, состоящим из трех целых чисел. Поэтому, когда необходимо получить доступ к целому числу в этом массиве, следует использовать первый индекс для указания номера массива, хранящего целые числа, а второй индекс — для указания номера целого числа в этом массиве. Рассмотрим следующий массив:

int ThreeRowsThreeColumns [3][3] = {{-501, 206, 2011}, {989, 101, 206}, {303, 456, 596}};

Он инициализирован способом, который можно рассматривать как три массива, каждый из которых содержит три целых числа. Здесь целочисленный элемент со значением 206 находится в позиции [0][1], а элемент со значением 456 — в позиции [2][2].

Следующая программа демонстрирует, как можно обращаться к целочисленными элементам в этом массиве.

*знак решетки* include <iostream>
using namespace std;
int main()
{
int ThreeRowsThreeColumns [3][3] =
{{-501, 206, 2011}, {989, 101, 206}, {303, 456, 596}};
cout << "Ряд 0: " << ThreeRowsThreeColumns [0][0] << " "
<< ThreeRowsThreeColumns [0][1] << " "
<<ThreeRowsThreeColumns [0][2] << endl;
cout << "Ряд 1: " << ThreeRowsThreeColumns [1][0] << " "
<< ThreeRowsThreeColumns[1][1] << " "
<< ThreeRowsThreeColumns[1][2] << endl;
cout << "Ряд 2: " << ThreeRowsThreeColumns[2][0] << " "
<< ThreeRowsThreeColumns[2][1] << " "
<< ThreeRowsThreeColumns[2][2] << endl;
return 0;
}

Результат

Ряд 0: -501 206 2011
Ряд 1: 989 101 206
Ряд 2: 303 456 596

Обратите внимание на способ обращения к элементам в построчном массиве, начинающемся с массива Ряд 0 (первый ряд с индексом 0) и заканчивающимся массивом Ряд 2(третий ряд с индексом 2). Поскольку каждый из рядов - это массив, синтаксис для обращения к третьему элементу в пером ряду такой, как в строке 10.

ПРИМЕЧАНИЕ - Длина кода в этой программе существенно увеличивается при увеличении количества элементов в массиве или его размерностей. Фактически в профессиональной среде разработки такой код неприменим. Для доступа ко всем элементам подобного массива используется вложенный цикл for. Код с применением цикла for существенно короче и меньше склонен к ошибкам, а кроме того, на его длину не влияет изменение количества элементов в массиве.

Строки в стиле С

Строки в стиле С — это частный случай массива символов. Вы уже видели несколько примеров таких строк в виде строковых литералов, когда писали такой код:

cout << "Hello World";

Это эквивалентно такому объявлению массива:

char SayHello[] = {'Н', 'е', 'l*, 'l', 'о', ' 'W', 'o', 'г', 'l*, 'd', '\0'};
cout << SayHello << endl;

Обратите внимание: последний символ в массиве — нулевой символ ' \ 0 '. Он также называется знаком окончания строки, поскольку указывает компилятору, что строка закончилась. Такие строки в стиле С — это частный случай символьных массивов, последним символом которых всегда является нулевой символ ' \ 0 *. Когда вы используете в коде строковый литерал, компилятор сам добавляет после него символ ' \ 0 '.

Если вставить символ ' \ 0 ' в середину массива, то это не изменит его размер; однако обработка строки, хранящейся в данном массиве, остановится на этой точке. Это демонстрирует следующая программа:

ПРИМЕЧАНИЕ - Символ ' \0 ' может показаться двумя символами, и, в самом деле, для его ввода следует нажать на клавиатуре две клавиши. Однако обратная косая черта - это специальный управляющий код, который компилятор понимает и воспринимает \0 как нуль, т.е. это способ указать компилятору вставить нулевой символ или нуль. Вы не можете ввести нулевой символ непосредственно, поскольку литерал ' 0' будет воспринят как символьный нуль с кодом ASCII 48, а не 0.

*знак решетки*include <iostream>
using namespace std;
int main()
{
char SayHello[] = {'H', 'e', l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0'};
cout « SayHello « endl;
cout « "Размер массива: " « sizeof(SayHello) « endl;
cout « "Замена пробела на нуль" « endl;
SayHello[5] = '\0';
cout « SayHello « endl;
cout « "Размер массива: " « sizeof(SayHello) « endl;
return 0;
}

Результат

Hello World
Размер массива: 12
Замена пробела на нуль
Hello
Размер массива: 12

Код строки 10 заменяет пробел в строке H e llo W o rld нулевым символом. Теперь у массива есть два нулевых завершающих символа, но используется первый, что и создает эффект. Когда пробел заменяется нулевым символом, отображаемая строка усекается до части H e llo . Метод s i z e o f () в строках 7 и 12 указывает, что размер массива не изменился, несмотря на изменение отображаемых данных.

ВНИМАНИЕ! - Если при объявлении и инициализации символьного массива в строке 5 программы выше вы забываете добавить символ ' \ 0 ', то после части Hello World вывод будет содержать случайный набор символов. Дело в том, что оператор cout не остановится на выводе массива, он будет продолжать вывод, пока не достигнет нулевого символа, даже если для этого придется перейти границы массива. Эта ошибка может нарушить вашу программу, а в некоторых случаях поставить под угрозу стабильность системы.

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

*знак решетки*include <iostream>
using namespace std;
int main()
{
cout << "Введите слово длиной не более 20 символов: "<< endl;
char UserInput [21] = {'\0'};
cin >> UserInput;
cout << "Длина входных данных: " << strlen (UserInput) << endl;
return 0;
}

Результат

Введите слово длиной не более 20 символов:
Don't UseThisProgram
Длина входных данных: 19

Опасность видна в выводе. Программа просит пользователя не вводить больше двадцати символов. Причина в том, что объявленный в строке 7 символьный буфер, предназначенный для хранения пользовательского ввода, имеет фиксированную статическую длину в 21 символ. Поскольку последний символ в строке должен быть нулевым ' \ 0 ', максимальная длина текста, хранимого буфером, ограничивается двадцатью символами. Обратите внимание на применение оператора strlen в строке 10 для вычисления длины строки. Он перебирает символьный буфер и подсчитывает количество символов, пока не достигает нулевого, который означает конец строки. Этот символ был вставлен в конец введенных пользователем данных оператором cin . Подобное поведение оператора strlen делает это опасным, поскольку он может легко пересечь границы символьного массива, если пользователь введет текст длиннее упомянутого предела.

Строки С++: Использование типа string

Стандартная строка C++ — самый эффективный способ работы и с текстовым вводом, и при манипуляции строками, например, при их конкатенации

ВНИМАНИЕ! - Приложения, написанные на языке С (или на языке C++ программистами с большим опытом в языке С), зачастую используют в своем коде функции копирования строк, такие как strcpy, функции конкатенации, такие как street, и определения длины строк, такие как strlen. Эти функции используют строки в стиле С и потому опасны, так как ищут завершающий нулевой символ и могут преодолеть границы символьного массива, если программист не гарантировал наличие завершающего нулевого символа

Язык C++ предоставляет мощное и в то же время безопасное средство манипулирования строками — класс string , представленный в программе ниже. Класс string реализован не на статическом массиве типа char неизменного размера, как строки в стиле С, и допускает увеличение размера, когда в нем необходимо сохранить больше данных.

*знак решетки*include <iostream>
*знак решетки*include<string>
using namespace std;
int main()
{
string Greetings ("Hello string!");
cout « Приветствия « endl;
cout « "Введите строку текста: " « endl;
string FirstLine;
getline(cin, FirstLine);
cout « "Введите еще один: " « endl;
string SecLine;
getline(cin, SecLine);
cout « "Результат конкатенации: " « endl;
string Concat = FirstLine + " " + SecLine;
cout « Concat « endl;
cout « "Копия сцепленной строки: "
string Copy;
Copy = Concat;
cout << Скопировано << endl;
cout <<"Длина строки функция concat : " << Concat.length() « endl;
return 0;
}

Результат

Hello string!
Введите строку текста:
I love
Введите еще один:
C++ strings
Результат конкатенации:
I love C++ strings
Копия сцепленной строки:
I love C++ strings
Длина строки функция concat: 18

Старайтесь понять вывод и связать его с соответствующими элементами в коде. Не беспокойтесь пока о новых синтаксических средствах. Программа начинается с отображения инициализированной в строке 7 строки Hello string!. Затем, в строках 12 и 16, она просит пользователя ввести две строки текста, которые сохраняются в переменных FirstLine и SecLine . Фактически конкатенация очень проста и выглядит как арифметическая сумма в строке 19, где даже пробел был добавлен к первой строке. Действие копирования — это простое присвоение в строке 24. Определение длины строки осуществляется при вызове метода length() в строке 27.

ПРИМЕЧАНИЕ - Для использования строк C++ в код необходимо включить заголовок string: *знак решетки* include <string>
Это можно заметить в строке 1 в программе выше

Резюме

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

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

Вы также узнали, что строки в стиле С — это частный случай символьного массива, где конец строки отмечается нулевым завершающим символом ' \0 ’. Кроме того, вы узнали, что язык C++ обеспечивает намного лучшую возможность — класс string , — предоставляющий удобные вспомогательные функции и позволяющий определить длину строк, объединять их и выполнять подобные действия.

Вопросы и ответы

Зачем заботиться об инициализации элементов статического массива?

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

Следует ли инициализировать элементы динамического массива по причинам, упомянутым в первом вопросе?

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

Когда имеет смысл использовать строки в стиле С, нуждающиеся в завершающем нулевом символе?

Только если кто-то приставил пистолет к вашей голове. Язык C++ предоставляет намного более безопасное средство — класс string , позволяющий любому программисту избежать использования строк в стиле С.

Включает ли длина строки завершающий нулевой символ?

Нет, не включает. Длина строки Hello World составляет 11 символов, включая пробел, но исключая завершающий нулевой символ

Хорошо, но если я все же хочу использовать строки в стиле С в символьных массивах, определенных мною. Каким должен быть размер используемого массива?

Здесь вы столкнетесь с одной из сложностей использования строк в стиле С. Размер массива должен быть на единицу больше размера наибольшей строки, которую он будет когда-либо содержать. Это необходимо для нулевого символа в конце самой длинной строки. Если бы строка Hello World была наибольшей, которую предстоит содержать символьному массиву, то ее длина составила бы 11 + 1 символ, т.е. 12 символов.

Контрольные вопросы

  1. Проверьте массив MyNumbers в самой первой программе. Каковы индексы первых и последних его элементов?
  2. Если необходимо позволить пользователю вводить строки, использовали бы вы строки в стиле С?
  3. Сколько символов насчитывает компилятор, встретив ' \ 0 ' ?
  4. Вы забываете завершить строку в стиле С нулевым символом. Что может случиться при ее использовании?

Упражнения

1. Объявите массив, представляющий клетки на шахматной доске; типом массива может быть перечисление, определяющее характер фигур на доске.

2. Отладка: Что не так с этим фрагментом кода?

int MyNumbers[5] = {0};
MyNumbers[5] = 450; // Присвоение значения 450 пятому элементу

3. Отладка: Что не так с этим фрагментом кода?

int MyNumbers[5];
cout « MyNumbers[3];

Ответы

Контрольные вопросы

  1. 0 и 4 — это отсчитываемые от нуля индексы первого и последнего элементов массива с пятью элементами.
  2. Нет, так как известна их небезопасность, особенно при обработке пользовательского ввода, поскольку они позволяют ввести строку длиннее массива.
  3. Один нулевой завершающий символ.
  4. Все зависит от того, как она используется. Если она используется в операторе cout, например, то механизм отображения будет читать последовательность-символов, пока не найдет завершающий нулевой символ. При его отсутствии он пересечет границы массива и, возможно, приведет к краху приложения.

Упражнения

  1. Вот что получилось. Приложение инициализируется значением ROOK (ладья), но оно достаточно простое, чтобы вы поняли все сами
int main()
{
enum SQUARE //enum - перечисление
{
NOTHING = 0,
PAWN,
ROOK,
KNIGHT,
BISHOP,
KING,
QUEEN
};
SQUARE ChessBoard[8] [8] ;
// Инициализировать клетки, содержащие ладьи
ChessBoard[0][0] = ChessBoard[0][7] = ROOK;
ChessBoard[7][0] = ChessBoard[7][7] = ROOK;
return 0;
}

2. Чтобы присвоить значение пятому элементу массива, необходим доступ к элементу MyNumbers [4], поскольку индекс отсчитывается от нуля

3. Обращение к четвертому элементу массива осуществляется до его инициализации или присвоения значения. Вывод будет непредсказуем. Всегда инициализируйте переменные и массивы; в противном случае они будут содержать последнее значение, хранившееся в зарезервированной для них области памяти