Освой самостоятельно С++ за 21 день.
Шрифт:
6: int main
7: {
8: // часовые
9: long sentinelOne[3];
10: long TargetArray[25]; // массив для записи данных
11: long sentinelTwo[3];
12: int i;
13: for (i=0; i<3; i++)
14: sentinelOne[i] = sentinelTwo[i] = 0;
15:
16: for (i=0; i<25; i++)
17: TargetArray[i] = 0;
18:
19: cout << "Test 1: \n"; // test current values (should be 0)
20: cout << "TargetArray[0]: " << TargetArray[0] << "\n";
21: cout << "TargetArray[24]: " << TargetArray[24] << "\n\n";
22:
23: for (i = 0; i<3; i++)
24: {
25: cout << "sentinelOne[" << i << "]: ";
26: cout << sentinelOne[i] << "\n";
27: cout << "sentinelTwo[" << i << "]: ";
28: cout << sentinelTwo[i]<< "\n";
29: }
30:
31: cout << "\nAssigning...";
32: for (i = 0; i<=25; i++)
33: TargetArray[i] = 20;
34:
35: cout << "\nTest 2: \n";
36: cout << "TargetArray[0]: " << TargetArray[0] << "\n";
37: cout << "TargetArray[24]: " << TargetArray[24] << "\n";
38: cout << "TargetArray[25]; " << TargetArray[25] << "\n\n";
39: for (i = 0; i<3; i++)
40: {
41: cout << "sentinelOne[" << i << "]: ";
42: cout << sintinel0ne[i]<< "\n";
43: cout << "sentinelTwo[" << i << "]: ";
44: cout << sentinelTwo[i]<< "\n";
45: }
46:
47: return 0;
48: }
Результат:
Test 1:
TargetArray[0]: 0
TargetArray[24]: 0
Sentinel0ne[0]: 0
SentinelTwo[0]: 0
SentinelOne[1]: 0
SentinelTwo[1]: 0
SentinelOne[2]: 0
SentinelTwo[2]: 0
Assigning...
Test 2:
TargetArray[0]: 20
TargetArray[24]: 20
TargetArray[25]: 20
Sentinel0ne[0]: 20
SentinelTwo[0]: 0
SentinelOne[1]: 0
SentinelTwo[1]: 0
SentinelOne[2]: 0
SentinelTwo[2]: 0
Анализ:
но значения этих массивов устанавливаются в 0. Если будет записано значение в массив TargetArray по адресу, выходящему за пределы этого массива, то значения массивов- часовых изменятся. Одни компиляторы ведут отсчет по возрастающей от адреса массива, другие — по убывающей. Именно поэтому используется два вспомогательных массива, расположенных по обе стороны от целевого массива TargetArray.
В строках 19-29 проверяется равенство нулю значений элементов массивов-часовых (Test 1). В строке 33 элементу массива TargetArray присваивается значение 20, но при этом указан индекс 25, которому не соответствует ни один элемент массива TargetArray.
В строках 36-38 выводятся значения элементов массива TargetArray (Test 2). Обратите внимание, что обрашение к элементу массива TargetArray[25] проходит вполне успешно и возвращается присвоенное ранее значение 20. Но когда на экран выводятся значения массивов-часовых Sentinel0na
Если далее в программе значения элементов массива SentinelOne будут использоваться в каких-то расчетах, то причину возникновения ошибки будет сложно определить. В этом состоит коварство ввода значений за пределы массива.
В нашем примере размеры массивов были заданы значениями 3 и 25 в объявлении массивов. Гораздо безопаснее использовать для этого константы, объявленные где- нибудь в одном месте программы, чтобы программист мог легко контролировать размеры всех массивов в программе.
Еще раз отметим, что, поскольку разные компиляторы по-разному ведут отсчет адресов памяти, результат выполнения показанной выше программы может отличаться на вашем компьютере.
Ошибки подсчета столбцов для забора
Ошибки с записью данных за пределы массива случаются настолько часто, что для них используется особый термин — ошибки подсчета столбов для забора. Такое странное название было придумано по аналогии с одной житейской проблемой — подсчетом, сколько столбов нужно вкопать, чтобы установить 10-метровый забор, если расстояние между столбами должно быть 1 м. Многие не задумываясь отвечают — десять. Вот если бы задумались и посчитали, то нашли бы правильный ответ — одиннадцать. Если вы не поняли почему, посмотрите на рис. 12.2.
Ошибка на единицу при установке индекса в обращении к массиву может стоить программе жизни. Нужно время, чтобы начинающий программист привык, что при обращении к массиву, состоящему из 25 элементов, индекс не может превышать значение 24 и отсчет начинается с 0, а не с 1. (Некоторые программисты потом настолько к этому привыкают, что в лифте нажимают на кнопку 4, когда им нужно подняться на пятый этаж.)
Примечание:Иногда элемент массива ИмяМассива[0] называют нулевым, а не первым. Но и в этом случае легко запутаться. Если элемент ИмяМассива[0] нулевой, то каким тогда будет элемент ИмяМассива[1]? Первым или вторым? И так далее... Каким будет элемент ИмяМассива[24]— двадцать четвертым или двадцать пятым? Правильно будет считать элемент ИмяМассива[0] первым, имеющим нулевой сдвиг.
Инициализация массива
Инициализацию массива базового типа (например, int или char) можно проводить одновременно с его объявлением. Для этого за выражением объявления массива нужно установить знак равенства (=) и в фигурных скобках список значений элементов массива, разделенных запятыми. Например:
int IntegerArray[5] = {10, 20, 30, 40, 50>;
В этом примере объявляется массив целых чисел IntegerArray и элементу IntegerArray[0] присваивается значение 10, элементу IntegerArray[ 1 ] — 20 И т.д.