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

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

Основные принципы создания собственных типов

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

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

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

Избегайте предопределенных типов Если есть хоть малейшая возможность, что тип может измениться, избегайте применения предопределенных типов везде, кроме определений typedef или type. Легко создать новые функционально-ориентированные типы - менять же данные в программе, использующей жестко закодированные типы, гораздо сложней. Более того, функционально-ориентированные типы частично документируют объявленные с ними переменные. Объявление Coordinate х сообщит вам об х гораздо больше, чем объявление float х. Используйте собственные типы везде, где только можно.

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

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

Не создавайте типы, которые легко перепутать с предопределенными. Существует возможность определить INT вместо INT32, но лучше сделать явное различие между типами, созданными вами, и типами, предоставленными языком программирования.



Рассмотрите вопрос создания класса вместо использования typedef Простые операторы typedef позволяют проделать большой путь в сторону сокрытия информации об исходном типе переменной. Однако иногда вам может потребоваться дополнительная гибкость и управляемость, которой позволяют добиться классы. Подробнее см. главу 6.

Контрольный список: основные данные Шр: со2е.сошлг06

I □ Не содержит ли код магические числа?

Перекрестная ссылка Список Предупреждаются ли в коде ошибки деления на ноль? вопросов, затрагивающих т- Очевидны ли преобразования типов? НЫ6 вообще, без подразделения □ Если переменные двух разных типов используются в одна конкретные шы, см, в кои- выражении, будет ли оно вычислено так, как вы это тройьном опиш главы 10. Они- едполагаете? сок вопросов по вариантам "рм"*»

именования см. в контрольном происходит ли сравнение переменных разных типов? списке главы 11. □ Компилируется ли программа без предупреждений ком-

пилятора?

Целые числа

□ Работают ли выражения, содержащие целочисленное деление так, как это предполагалось?

□ Предупреждаются ли в целочисленных выражениях проблемы целочисленного переполнения?

Числа с плавающей запятой

□ Не содержит ли код операции сложения и вычитания слишком разных по величине чисел?

□ Предупреждаются ли в коде ошибки округления?

□ Не выполняется сравнение на равенство чисел с плавающей запятой?

Символы и строки

□ Не содержит ли код магических символов и строк?

□ Свободны ли операции со строками от ошибки потери единицы?

□ Различаются ли в коде на С строковые указатели и массивы символов?

□ Соблюдается ли в коде на С соглашение об объявлении строк с длиной C0NSTANT+11

□ Используются ли в с массивы символов вместо указателей там, где это допустимо?

□ Инициализируются ли в С строки с помощью NULL во избежание бесконечных строк?

□ Используются ли в коде на С strncpyQ вместо strcpyQ? А strncatQ и strncmpQ? Логические переменные

□ Используются ли в программе дополнительные логические переменные для документирования проверок условия?

□ Используются ли в программе дополнительные логические переменные для упрощения проверок условия?



Перечислимые типы

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

□ Используются ли перечислимые типы вместо логических переменных, если все значения переменной не могут быть переданы с помощью true и false?

□ Проверяются ли некорректные значения перечислимых типов в условных операторах?

□ Зарезервирован ли первый элемент перечислимого типа как недопустимый? Перечислимые константы

□ Используются ли в программе именованные константы вместо магических чисел для объявления данных и границ циклов?

□ Используются ли именованные константы последовательно, чтобы одно значение не представлялось в одном месте константой, а в другом - литералом?

Массивы

□ Находятся ли все индексы массива в его границах?

□ Свободны ли ссылки на массив от ошибок потери единицы?

□ Указаны ли все индексы многомерных массивов в правильном порядке?

□ В правильном ли порядке используются переменные-индексы во вложенных циклах, не происходит ли пересечения индексов?

Создание типов

□ Используются ли в программе отдельные типы для каждого вида данных, который может измениться?

□ Ориентируются ли имена типов на реальные сущности, которые эти типы представляют, а не на типы языка программирования?

□ Достаточно ли наглядны имена типов, чтобы помочь документированию объявлений данных?

□ Не произошло ли переопределение предопределенных типов?

□ Рассматривался ли вопрос создания нового класса вместо простого переопределения типа?

Ключевые моменты

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

Создание собственных типов, если ваш язык это позволяет, упрощает модификацию вашей программы и делает ее более самодокументируемой.

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



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.0021