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