В языке "C" предусмотрен и оператор GOTO, которым беско-нечно злоупотребляют, и метки для ветвления. С формальнойточки зрения оператор GOTO никогда не является необходимым,и на практике почти всегда можно обойтись без него. Мы неиспользовали GOTO в этой книге. Тем не менее, мы укажем несколько ситуаций, где операторGOTO может найти свое место. Наиболее характерным являетсяего использование тогда, когда нужно прервать выполнение внекоторой глубоко вложенной структуре, например, выйти сразуиз двух циклов. Здесь нельзя непосредственно использоватьоператор BRеак, так как он прерывает только самый внутреннийцикл. Поэтому: FOR ( ... ) FOR ( ... ) { ... IF (DISASTER) GOTO ERROR; } ... ERROR: CLEAN UP THE MESS Если программа обработки ошибок нетривиальна и ошибки могутвозникать в нескольких местах, то такая организация оказыва-ется удобной. Метка имеет такую же форму, что и имя перемен-ной, и за ней всегда следует двоеточие. Метка может бытьприписана к любому оператору той же функции, в которой нахо-дится оператор GOTO. В качестве другого примера рассмотрим задачу нахожденияпервого отрицательного элемента в двумерном массиве. (Много-мерные массивы рассматриваются в главе 5). Вот одна из воз-можностей: FOR (I = 0; I < N; I++) FOR (J = 0; J < M; J++) IF (V[I][J] < 0) GOTO FOUND; /* DIDN'T FIND */ ...FOUND: /* FOUND ONE AT POSITION I, J */ ... Программа, использующая оператор GOTO, всегда может бытьнаписана без него, хотя, возможно, за счет повторения неко-торых проверок и введения дополнительных переменных. Напри-мер, программа поиска в массиве примет вид: FOUND = 0;FOR (I = 0; I < N && !FOUND; I++) FOR (J = 0; J < M && !FOUND; J++) FOUND = V[I][J] < 0;IF (FOUND) /* IT WAS AT I-1, J-1 */ ...ELSE /* NOT FOUND */ ... Хотя мы не являемся в этом вопросе догматиками, нам всеже кажется, что если и нужно использовать оператор GOTO, товесьма умеренно.
* 4. Функции и структура программ *
Функции разбивают большие вычислительные задачи на ма-ленькие подзадачи и позволяют использовать в работе то, чтоуже сделано другими, а не начинать каждый раз с пустого мес-та. Соответствующие функции часто могут скрывать в себе де-тали проводимых в разных частях программы операций, знатькоторые нет необходимости, проясняя тем самым всю программу,как целое, и облегчая мучения при внесении изменений. Язык "C" разрабатывался со стремлением сделать функцииэффективными и удобными для использования; "C"-программыобычно состоят из большого числа маленьких функций, а не изнескольких больших. Программа может размещаться в одном илинескольких исходных файлах любым удобным образом; исходныефайлы могут компилироваться отдельно и загружаться вместенаряду со скомпилированными ранее функциями из библиотек. Мыздесь не будем вдаваться в детали этого процесса, посколькуони зависят от используемой системы. Большинство программистов хорошо знакомы с "библиотечны-ми" функциями для ввода и вывода /GETCHAR , PUTCHAR/ и длячисленных расчетов /SIN, COS, SQRT/. В этой главе мы сообщимбольше о написании новых функций.