Программирование >>  Обобщенные обратные вызовы 

1 ... 62 63 64 [ 65 ] 66 67 68 ... 84


main о {

int ai[10] = { 15,12,13,14,18,11,10,17,16,19 };

cout ################# endl; std: :vector<i nt> vecai(ai, ai +10); int aidxtbl[10];

sort idxtbl(vecai.beginO, vecai.endC), aidxtbl);

for (int i=0; i <10; i++)

cout i= i

, aidxtbl[i]= aidxtbl[i]

, ai[aidxtbl[i]]= ai[aidxtbl[i]]

endl;

cout ################# endl;

Решение

Небольшая проповедь о ясности

1. Кто выигрывает от ясного, понятного исходного текста? Если говорить коротко - практически все.

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

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

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

> Рекомендация

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

Разбор индексных таблиц

2. Приведенный далее исходный текст представляет интересную и, несомненно, полезную идиому создания индексных таблиц над существующими контейнерами. Более детальную информацию вы можете почерпнуть из статьи [HicksOO].



Оцените приведенный далее исходный текст и найдите:

a) механические ошибки, такие как неверный синтаксис или непереносимые соглашения;

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

Позвольте мне повториться и напомнить, что этот код содержит интересную и весьма полезную идиому. Мне часто требуется доступ к одному и тому же контейнеру разными способами, например, в различном порядке сортировки. По этой причине было бы неплохо иметь один основной контейнер, который хранит данные (например, vector<Employee>) и вторичные контейнеры итераторов, указывающих на элементы основного контейнера и ревизующие различные способы доступа (например, set<vector<Emp1oyee>::iterator,Funct>, где Funct - функтор, который косвенно сравнивает объекты Employee, выполняя упорядочение объектов, отличающееся от того, в котором они физически хранятся в контейнере (в данном случае - в vector)).

Кроме сказанного, имеет значение и стиль. Автор приведенного фрагмента любезно позволил мне воспользоваться им в качестве учебного примера, и я не пытаюсь дразнить его здесь. Я только адаптирую методику, давно открытую таким светилом, как Плоджср (Р. J. Plauger) , пытаясь дать вам рекомендации по кодированию на основе опубликованных исходных текстов. Я критиковал чужие программы и раньше, причем я уверен, что мои программы также подлежат критике.

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

Исправление механических ошибок

а) механические ошибки, такие как неверный синтаксис или непереносимые соглашения

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

#include <algorith>

1. Правильно указывайте стандартные заголовочные файлы. Здесь заголовочный файл <algorithm> ошибочно назван <algorith>. Мое первое предположение было, что это, вероятно, артефакт файловой системы с 8-символьными именами, использовавшейся для тестирования первоначальной версии кода, но даже моя старая версия VC-I-+ на старой версии Windows (с использованием файловой системы с именами 8.3) отказалась компилировать этот код. В любом случае, это имя не является стандартным, и даже при работе со старыми файловыми системами компилятор должен поддерживать стандартные длинные имена (даже если он затем преобразует их в более короткие имена файлов, или даже если физически файлы не используются вообще).

Теперь обратимся к строке

mai п С)

2. Корректно определяйте функцию main. Приведенная здесь сигнатура функции main никогда не была стандартом С++ [С++98], хотя и является согласующимся со стандартом расширением (если компилятор выдает соответствующее предупреждение). Такая сигнатура была корректна в языке С до принятия стандарта 1999 года.

Плоджер Ф., Керни1ан Б. Элементы стиля программирования. - М.; Радио и связь, 1984. - Прим. ред.



в котором действовало правило о неявном int, но ни в С+ + , ни в С99 [С99] она не верна. Из стандарта С+ + :

§3,6.1/2: переносимый коя должен определять main либо как int main(), либо как int main(int, char*[]).

§7/7, сноска 78, и §7.1.5/2 сноска 80: неявный i nt запрещен.

Приложение С (совместимость), комментарий к 7.1.5/4: явно указано, что голое объявление main() не корректно в С++, функция main должна определяться какint main().

> Рекомендация

Не полагайтесь на неявный int: стандартом С++ .это не предусматривается. В частности, void mainO или maiп() никогда не были стандартными в С++, хотя многие компиляторы поддерживают их в качестве расширений.

cout ################# end! ;

3. Всегда включайте заголовки для тех типов, определения которых вам требуются. Программа использует cout и endl, но не включает #include <iostream>. Почему, тем не менее, программа работала в системе ее разработчика? Потому что стандартные загологючиые файлы С++ могут включать друг друга, но в отличие от С, С++ не определяет, какие стандартные заголовочные файлы включают другие стандартные заголовочные файлы и какие именно.

В нашем случае профамма включает <vector> и <algorithm>, и, видимо, в исходной системе один из этих заголовочных файлов включал также <iostream> - непосредственно или опосредованно. Такая профамма могла работать в системе у ее автора, может быть, она даже заработает и у меня, но это непереносимый и нездоровый стиль.

4. Следуйте рекомендациям задачи 39 из книги More Exceptional С++ lSutier02] (задача 10.10 русского издания) о пространствах имен. Говоря о cout и endl, программа должна кв,ыифипировать их с использованием std: :, либо применить директивы using std:: cout; и using std: :endl ;. К сожалению, это распросфанено среди программистов - забывать о квалификаторах области видимости пространства имен. Спешу заметить, что автор фрагмента корректно указал пространство имен vector и sort, что является хорошим стилем профаммирования.

Улучшение стиля

б) стилистические улучшения, которые могут повысить ясность, степень повторного

использования и сопровождаемости исходного текста.

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

template <class RAlter> struct sort idxtbl paiг

RAlter it; int i;

bool operator<C const sort idxtbl pai г & s )

{ return C*it) < (*(s.it)); } void set С const RAlter& it, int i ) { it= it; i= i; } sort idxtbl paiг() {}

5. Корректно и последовательно используйте квалификатор const. В частности, sort idxtbl pai г: :operator< не модифицирует *this, так что этот оператор следует объявить как константную функцию-член.



1 ... 62 63 64 [ 65 ] 66 67 68 ... 84

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика