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

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

матирования многострочных вызовов методов работает хорошо при последовательном применении.

При переносе строк в управляющем выражении делайте отступ стандартного размера При нехватке места для цикла /ог, цикла while или оператора if перенося строку, сделайте такой же отступ, как и в выражениях внутри цикла или после условия В листинге 31-45 приведены два примера:

Листинг 31-45. Примеры отступов при переносе строк в управляющих выражениях (Java)

while ( ( pathName[ startPath + position ]!==; ) &&

- В продолжении строки отступ содержит стандартное количество пробелов...

-> ( ( StartPath + position ) pathName.length() ) ) {

for ( int employeeNum = employee.first + employee.offset;

- ...так же, как и в этом случае.

>г employeeNum < employee.first + employee.offset + employee.total; employeeNum++ ) {

Приведенный код соответствует критериям, установленным цщщщ штг иногда ранее в этой главе. Перенос строки выполняется логично сложных условий лучше - в нем всегда есть отступ относительно выражения, кото- юего поместить их в логичес-рое он продолжает. Дальнейшее выравнивание может вы- ш% функции (см. подраздел полняться как обычно - новая строка занимает всего на «Упрощение сложных выраже-несколько пробелов больше, чем исходный вариант. Он так раздела 19.1). же читаем, как и любой другой код, и его так же просто

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

Не выравнивайте правые части выражений присваивания В первом издании этой книги я рекомендовал выравнивать правые части выражений, содержащие присваивания (листинг 31-46):

Листинг 31-46. Примеры форматирования в конце строки, используемого при выравнивании выражений присваивания, - плохая практика (Java)

customerPurchases = customerPurchases + CustomerSales( CustomerlD ); customerBill - customerBill + customerPurchases;

totalCustomerBill = customerBill + PreviousBalance( customerlD ) +

LateCharge( customerlD ); customerRating = Rating( customerlD, totalCustomerBill );



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

Для обеспечения единообразия с другими принципами отступов, а также учитывая вопросы удобства сопровождения, обращайтесь с группами выражений, содержащими операции присваивания, так же, как вы бы обращались с любыми другими выражениями (листинг 31-47):

Листинг 31-47. Пример использования стандартных отступов для выравнивания выражений присваивания - хорошая практика (Java)

customerPurchases = customerPurchases + CustomerSales( CustomerlD );

customerBill = customerBill + customerPurchases;

totalCustomerBill = customerBill + PreviousBalance( customerlD ) +

LateCharge( customerlD ); customerRating = Rating( customerlD, totalCustomerBill );

При переносе строк в выражениях присваивания применяйте отступы стандартного размера В листинге 31-47 при переносе строки в третьем присваивании используется стандартный размер отступа. Это сделано с той же целью, что и отказ от специального форматирования выражений присваивания: из общих соображений читаемости и удобства сопровождения.

Размещение одного оператора на строке

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

i 0; j = 0; к = 0; DestroyBaclLoopNames( i, j, к );

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

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

Размещение каждого оператора на отдельной строке дает точное представление о сложности программы. При этом не скрывается сложность из-за того, что сложные операторы выглядят тривиальными. Сложные операторы и выглядят сложными, простые - простыми.



Размещение нескольких операторов на одной строке не peinapetiiiit тш т utm-помогает современным компиляторам в оптимизации, щцзар» Щ)Ойзтцц1Твт«ности на Сегодняшние оптимизирующие компиляторы не нужда- ртт mm ci*. tmu 25 и Ж ются в подсказках, сделанных с помощью форматирования (см. ниже).

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

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

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

Когда строка содержит только один оператор, его легко редактировать - можно удалить или временно закомментировать всю строку. Если же на одной строке вы разместили несколько операторов, вам придется выполнять редактирование между остальными операторами.

В С++ избегайте выполнения нескольких операций в одной строке (побочные эффекты) Побочные эффекты - это последствия выполнения некоторого выражения, проявляющиеся в дополнение к основным результатам выполнения этого выражения. Так, в С++ оператор ++, расположенный на одной строке с другими операторами, приводит к проявлению побочного эффекта. Присваивание значения переменной и применение левой части этого присваивания в условном операторе также является примером побочного эффекта.

Побочные эффекты снижают читаемость кода. Например, если п равно 4, что напечатает выражение, приведенное в листинге 31-48?

Листинг 31-48. Пример непредсказуемого побочного эффекта (С++)

PrintMessage( ++п, п + 2 );

4 и б? Или 5 и 7? А может, 5 и б? Правильный ответ: «Ни то, ни другое и не третье». Первый аргумент -++п - равен 5. Но язык С++ не определяет порядок вычисления условий выражения или аргументов функции. Поэтому компилятор может вычислить второй аргумент, п + 2, либо до, либо после первого аргумента, и результат может быть равен 6 или 7 в зависимости от компилятора. В листинге 31-49 показано, как переписать это выражение, чтобы прояснить свои намерения:



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