Шрифт:
{
int y;
у = (x < 0) ?
– x : x; /* вспомните операцию ?: */
return (у ); /* возвращает значение у вызывающей программе */
}
Результат работы программы выглядит так:
10 0 22
Сначала вспомним операцию условия ?:. Эта операция в функции abs выполняется следующим образом: если x меньше 0, у полагается равным – x; в противном случае у полагается равным x. Это как раз то, что нам нужно, поскольку если x равен – 5, то у равен – (-5), т. e. 5.
Ключевое слово return указывает на то, что значение выражения, заключенного в круглые скобки, будет присвоено функции, содержащей это ключевое слово. Поэтому, когда функция abs впервые вызывается нашим драйвером, значением abs(a) будет число 10, которое затем присваивается переменной d.
Переменная у является внутренним объектом функции abs, но значение у передается в вызывающую программу с помощью оператора return. Действие, оказываемое оператором
d = abs(a);
по-другому можно выразить так:
abs(a);
d = у;
Можно ли в действительности воспользоваться такой записью? Нет, так как вызывающая программа даже не подозревает о том, что переменная у существует.
Возвращаемое значение можно присвоить переменной, как в нашем примере, или использовать как часть некоторого выражения, например, следующим образом:
answer = 2*abs(z) + 25;
printf(" %d\n" , abs(-32 + answer));
Оператор return оказывает и другое действие. Он завершает выполнение функции и передает управление следующему оператору в вызывающей функции. Это происходит даже в том случае, если оператор return является не последним оператором тела функции. Следовательно, функцию abs мы могли бы записать следующим образом:
/* функция, вычисляющая абсолютную величину числа,
вторая версия */
abs(x) int x;
{
if(x < 0)
return(-x);
else
relurn(x);
}
Эта версия программы проще, и в ней не используется дополнительная переменная у. Для пользователя, однако, обе версии неразличимы, поскольку у них имеется один и тот же вход и они обеспечивают один и тот же выход. Только внутренние структуры обеих функций различны. Даже версия данной программы, приведенная ниже, работает точно так же:
/* функция, вычисляющая абсолютную величину числа,
третья версия */
abs(x) int(x);
{
if (x < 0)
return(-x);
else
return(x);
printf(" Профессор Флеппард - болван. \n");
}
Наличие оператора return препятствует тому, чтобы оператор печати printf когда-нибудь выполнился в программе. Профессор Флеппард может пользоваться в своих программах объектным кодом, полученным в результате компиляции данной функции, и никогда не узнает об истинных чувствах своего студента-программиста.
Вы можете также использовать просто оператор return;
Его применение приводит к тому, что функция, в которой он coдержится, завершает свое выполнение и управление возвращается в вызывающую функцию. Поскольку у данного оператора отсутствует выражение в скобках, никакое значение при этом не передается функции.
ЛОКАЛЬНЫЕ ПЕРЕМЕННЫЕ
Мы уже несколько раз касались вопроса о том, что переменные в функции являются ее внутренними переменными и "не известны" вызывающей функции. Аналогично переменные вызывающей функции не известны вызываемой функции. Вот почему для связи с ней, т. е. для передачи значений в нее и из нее, мы пользуемся аргументами и оператором return.
Переменные, известные только одной функции, а именно той, которая их содержит, называются "локальными" переменными. До сих пор это был единственный вид переменных, которыми мы пользовались, но в языке Си допускается наличие переменных, известных нескольким функциям. Такие нелокальные переменные называются "глобальными", и мы вернемся к ним позже. Теперь же мы хотим подчеркнуть, что локальные переменные являются действительно локальными. Даже в том случае, если мы используем одно и то же имя для переменных в двух различных функциях, компилятор (и, таким образом, компьютер "считает" их разными переменными. Мы можем показать это, используя операцию & (не путайте с операцией &&).