Программирование >>  Поддержка объектно-ориентированного программирования 

1 ... 25 26 27 [ 28 ] 29 30 31 ... 120


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

void f()

int i;

int j;

for ( i = 0; i < n; i++) for (j = 0; j<m; j++)

if (nm[i][j] == a) goto found; здесь a не найдено

...

found:

nm[i][j] == a

Есть еще оператор continue, который позволяет перейти на конец цикла. Что это значит, объяснено в $$3.1.5.

3.4 Комментарии и расположение текста

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

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

[1 ] осмысленный,

[2] действительно описывает программу, [3] не устарел.

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

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

переменную v необходимо инициализировать. переменная v может использоваться только в функции f() . до вызова любой функции из этого файла необходимо вызвать функцию init() .

в конце своей программы вызовите функцию cleanup() . не используйте функцию weird() . функция f() имеет два параметра.

При правильном программировании на С++ такие комментарии обычно оказываются излишними. Чтобы именно эти комментарии стали ненужными, можно воспользоваться правилами связывания ($$4.2) и областей видимости, а также правилами инициализации и уничтожения объектов класса ($$5.5).

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

a = b + c; a принимает значение b+c

count++; увеличим счетчик count

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



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

Можно рекомендовать такой стиль введения комментариев в программу:

[1 ] начинать с комментария каждый файл программы: указать в общих чертах, что в ней определяется, дать ссылки на справочные руководства, общие идеи по сопровождению программы и т.д.;

[2] снабжать комментарием каждое определение класса или шаблона типа;

[3] комментировать каждую нетривиальную функцию, указав: ее назначение, используемый алгоритм (если только он неочевиден) и, возможно, предположения об окружении, в котором работает функция;

[4] комментировать определение каждой глобальной переменной;

[5] давать некоторое число комментариев в тех местах, где алгоритм неочевиден или непереносим;

[6] больше практически ничего.

Приведем пример:

tbl.c: Реализация таблицы имен.

Использован метод Гаусса

см. Ральстон Начальный курс по ... стр. 411.

в swap() предполагается, что стек AT&T начинается с 3B20.

/************************************

Авторские права (c) 1991 AT&T, Inc Все права сохранены

**************************************/

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

Заметим, что если в функции используются только комментарии вида , то любую ее часть можно сделать комментарием с помощью /* */, и наоборот.

3.5 Упражнения

1 . (*1 ) Следующий цикл for перепишите с помощью оператора while:

for (i=0; i<max length;

if (input line[i] == ?) quest count++;

Запишите цикл, используя в качестве его управляющей переменной указатель так, чтобы условие имело вид *p==?.

2. Укажите порядок вычисления следующих выражений, задав полную скобочную структуру:

a = b + c * d << 2 & 8 a & 077 != 3

a == b a == c && c < 5 c = x != 0

0 <= i < 7

f(1,2) + 3

a = - 1 + + b -- - 5 a = b == c ++ a = b = c = 0

a[4][2] *= * b ? c : * d * 2 a-b, c=d



Каков может быть смысл этой функции?

11 . (*2) Напишите функцию atoi(), которая имеет параметр - строку цифр и возвращает соответствующее ей целое. Например, atoi( 1 23 ) равно 1 23. Измените функцию atoi() так, чтобы она могла переводить в число последовательность цифр не только в десятичной, но и в восьмеричной и шестнадцатеричной записи, принятой в С++. Добавьте возможность перевода символьных констант С++. Напишите функцию itoa() для перевода целого значения в строковое представление.

12. (*2) Перепишите функцию get token() ($$3.12) так, чтобы она читала целую строку в буфер, а затем

3. (*2) Укажите 5 различных конструкций на С++, значение которых неопределено.

4. (*2) Приведите 1 0 разных примеров непереносимых конструкций на С++.

5. (*1 ) Что произойдет при делении на нуль в вашей программе на С++? Что будет в случае переполнения или потери значимости?

6. Укажите порядок вычисления следующих выражений, задав их полную скобочную структуру:

*p++

*-- p

++a--

(int*)p->m *p.m

*a[i]

7. (*2) Напишите такие функции: strlen() - подсчет длины строки, strcpy() - копирование строк и strcmp() - сравнение строк. Какими должны быть типы параметров и результатов функций? Сравните их со стандартными версиями, имеющимися в <string.h> и в вашем руководстве.

8. Выясните, как ваш транслятор отреагирует на такие ошибки:

void f(int a, int b)

if (a = 3) ... if (a&077 == 0) ... a := b+1;

Посмотрите, какова будет реакция на более простые ошибки.

9. (*2) Напишите функцию cat(), которая получает два параметра-строки и возвращает строку, являющуюся их конкатенацией. Для результирующей строки используйте память, отведенную с помощью new. Напишите функцию rev() для перевертывания строки, переданной ей в качестве параметра. Это означает, что после вызова rev(p) последний символ p станет первым и т.д.

1 0. (*2) Что делает следующая функция?

void send(register* to, register* from, register count) Псевдоустройство. Все комментарии сознательно удалены

register n=(count+7)/8; switch (count%8) {

case 0: do { *to++ = *from++;

case 7: *to++ = *from++;

case 6: *to++ = *from++;

case 5: *to++ = *from++;

case 4: *to++ = *from++;

case 3: *to++ = *from++;

case 2: *to++ = *from++;

case 1: *to++ = *from++;

} while (--n>0);



1 ... 25 26 27 [ 28 ] 29 30 31 ... 120

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