/* функция, вычисляющая абсолютную величину числа,
вторая версия */
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.
Переменные, известные только одной функции, а именно той, которая их содержит, называются " локальными " переменными. До сих пор это был единственный вид переменных, которыми мы пользовались, но в языке Си допускается наличие переменных, известных нескольким функциям. Такие нелокальные переменные называются " глобальными ", и мы вернемся к ним позже. Теперь же мы хотим подчеркнуть, что локальные переменные являются действительно локальными. Даже в том случае, если мы используем одно и то же имя для переменных в двух различных функциях, компилятор (и, таким образом, компьютер "считает" их разными переменными. Мы можем показать это, используя операцию &(не путайте с операцией &&).
НАХОЖДЕНИЕ АДРЕСОВ: ОПЕРАЦИЯ &
В результате выполнения операции & определяется адрес ячейки памяти, которая соответствует переменной. Если pooh- имя переменной, то & pooh- ее адрес. Можно представить себе адрес как ячейку памяти, но можно рассматривать его и как метку, которая используется компьютером, для идентификации переменной. Предположим, мы имеем оператор
pooh = 24;
Пусть также адрес ячейки, где размещается переменная pooh- 12126. Тогда в результате выполнения оператора
printf(" %d %d\n" , pooh, &pooh);
получим
24 12126
Более того, машинный код, соответствующий первому оператору, словами можно выразить приблизительно так: "Поместить число 24 в ячейку с адресом 12126".
Воспользуемся указанной выше операцией для проверки того, в каких ячейках хранятся значения переменных, принадлежащих разным функциям, но имеющих одно и то же имя.
/* контроль адресов */
main( )
{
int pooh = 2, bah = 5;
printf(" Вmain( ), pooh = %d и&pooh = %u \n" , pooh, &pooh);
printf('B main( ), bah = %d и&bah = %u\n>/, bah, &bah);
mikado(pooh);
}
mikado(bah) int bah;
{
int pooh = 10;
printf("B mikado( ), pooh = %d и&pooh = %u\n, pooh, &pooh);
printf(" Вmikado( ), bah = %d и&bah = %u\n" , bah, &bah);
}
Мы воспользовались форматом %u(целое без знака) для вывода на печать адресов на тот случай, если их величины превысят максимально возможное значение числа типа int. В нашей вычислительной системе результат работы этой маленькой программы выглядит так:
Вmain( ), pooh = 2 и&pooh = 56002
B main( ), bah = 5 и&bah = 56004
B mikado( ), pooh = 10 и&pooh =55996
В mikado( ), bah = 2 и &bah = 56000.
О чем это говорит? Во-первых, две переменные poohимеют различные адреса. То же самое верно и относительно переменных bah. Следовательно, как и было обещано, компьютер рассматривает их как четыре разные переменные. Во-вторых, при вызове mikado(pooh)величина ( 2) фактического аргумента ( poohиз main( )) передастся формальному аргументу ( bahиз mikado( )). Обратите внимание, что было передано только значение переменной. Адреса двух переменных ( poohв main( )и bahв mikado( )) остаются различными.
Читать дальше