Главная - Литература

0 1 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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 [99] 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294

Пример еще более понятного кода (Visual Basic)

For month = 1 To NUM MONTHS IN YEAR

profit( month ) = revenue( month ) - expense( month ) Next

Этот пример выглядит весьма неплохо, но мы можем сделать еще один шаг вперед, применив перечислимый тип:

Пример очень понятного кода (Visual Basic)

For month = Month January To Month December

profit( month ) = revenue( month ) - expense( month ) Next

В последнем примере не может возникнуть никаких сомнений относительно назначения цикла. Даже если вы считаете, что литеральное значение безопасно, используйте вместо него именованную константу. Фанатично искорените литералы из вашего кода. С помощью текстового редактора выполните поиск 2,3,4,5, 6, 7, 8 и 9, чтобы убедиться, что вы не используете их случайно.

Имитируйте именованные константы с помощью {едсцац ьт$ D$ ищи-переменных или классов правильной области види- ац еречйлшых тиш см. мости Если ваш язык не поддерживает именованные кон- падаа№ Шщ вш Пт не станты, их можно создать. Подход, аналогичный приведен- поддерживает перечйсяимыв ному выше Java-примеру, имитирующему перечислимые рЩш типы, позволяет получить преимущества использования

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

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

12.8. Массивы

Массивы - простейшие и наиболее часто используемые типы структурированных данных. В некоторых языках это единственный вид структурированных данных. Массивы состоят из группы элементов одинакового типа, доступ к которым осуществляется напрямую по индексу.

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



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

Обдумайте применение контейнеров вместо массивов или рассматривайте массивы как последовательные структуры Некоторые именитые в компьютерной науке люди предлагали запретить произвольный доступ к массиву, заменив его последовательным (Mills and Linger, 1986). Аргументтруют они это тем, что произвольный доступ к массиву похож на случайные операторы goto в программе: их применение приводит к неаккуратному, подверженному ошибкам коду, в корректности которого сложно быть уверенным. Поэтому вместо массивов предлагается использовать множества, стеки и очереди, доступ к элементам которых выполняется последовательно.

Проведя небольшой эксперимент, Миллз (Mills) и Линджер (Linger) выяснили, что разработанный таким образом проект потребовал использования меньшего числа переменных и меньшего числа ссылок на эти переменные. То есть проект был относительно эффективнее, что привело к созданию более надежного ПО.

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

Гре«реш9я есьша Вопросы Проверяйте конечные точки массивов Как бывает по-прйшшйя «йсшов й Цйшв лезно продумать применение конечных точек в операторе имеют 1*ного общего, Йодрод- цикла, так и вы сможете обнаружить немало ошибок, прове-нее о микяах см. главу 16. рив крайние элементы массивов. Задайтесь вопросом, правильно ли выполняется доступ к первому элементу массива или случайно используется элемент перед ним либо после него. А что с последним элементом? Нет ли в коде ошибки потери единицы? И, наконец, спросите себя, правильно ли код обращается к элементам в середине массива.

В многомерном массиве убедитесь, что его индексы ги:пользуются в правильном порядке Очень легко Н2т\\с2.тъ Array[ i ][ j имея в виду Arrayf j ][ i J, так что не жалейте времени для проверки правильного порядка индексов. Попробуйте использовать более значимые имена, чем / и у, когда их назначение не вполне очевидно.

Остерегайтесь пересечения индексов При использовании вложенных циклов легко написать Лгг</"У7, имея в виду Аггау[ i J. Перемена мест индексов называется «пересечением индексов» (index cross-talk). Проверьте эту возможность. Опять же, используйте более значимые имена индексов, чем / и j\ чтобы ошибки пересечения изначально сложнее было совершить.

В языке С для работы с массивами используйте макрос ARRAYJLENGTHQ

Вы можете добавить гибкости вашей работе с массивами, определив макрос LENGTHO.

Пример определения макроса ARRAY LENGTHO на языке С

#clefine ARRAY LENGTH( х ) (sizeof(x)/sizeof(х[0]))



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

Пример использования макроса ARRAY LENGTHO для операций с массивами на языке С

ConsistencyRatios[] =

{ 0.0, 0.0, 0.58, 0.90, 1.12,

1.24, 1.32, 1.41, 1.45, 1.49,

1.51, 1.48, 1.56, 1.57, 1.59 };

г- Вот здесь используется макрос.

->for ( ratioldx = 0; ratioldx < ARRAY LENGTH( ConsistencyRatios ); ratioIdx++ );

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

12.9. Создание собственных

типов данных (псевдонимы)

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

Чтобы оценить возможности создания типов, представьте, что церекрвешш штш 8о многих вы пишете программу для преобразования координат из сис- случаях лучше создавать шсс, темы х,у,гъ широту, долготу и высоту. Вам кажется, что могуг ц%ц простой ш mmt* Пол-потребоваться числа с плавающей запятой двойной точное- робиаа см. тщ ти, но пока вы абсолютно в этом не уверены, предпочитаете

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

Пример создания типа (С++)

typedef float Coordinate; для координатных переменных

Это определение объявляет новый тип Coordinate, функционально идентичный типу float. Чтобы задействовать этот тип, вы просто объявляете с ним переменные точно так же, как и с любым предопределенным типом вроде float. Пример:



0 1 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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 [99] 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294



0.0076