Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на C / C++ / Нейбауэр А. Моя первая программа на С.doc
Скачиваний:
182
Добавлен:
02.05.2014
Размер:
3.75 Mб
Скачать

Возврат значений типа float

В тех случаях, когда значения, возвращаемые функцией, относятся к типу целочисленных или символьных, определение типа перед именем функции не является строго обязательным. Си изначально построен таким образом, чтобы воспринимать только данные типа int или char, так что, если тип не указан, Си посчитает, что возвращаемое значение относится к типу int или char.

Рис. 7.8. Определение функции типа float

Если возвращаемые данные относятся к числам с плавающей точкой, необходимо сделать две вещи:

  1. Указать тип float перед именем функции.

  2. Определить саму функцию.

Функция определяется перед main() так же, как внешняя переменная. На рис.7.8 показано, как это сделать. Инструкция

float square();

указывает компилятору, что он будет иметь дело с функцией типа float. За исключением определения функции и ввода данных другого типа, приведенная на рисунке программа идентична программе вычисления квадрата целых чисел.

Большинство компиляторов позволяет определять тип функции и внутри main():

main()

{

float number, value, square();

Если ваш компилятор не позволяет этого делать, определяйте функцию всегда перед main().

Использование return() в функции main()

Возможно, вы задумались над тем, что означает запись return(0) в функции main(). Обычно мы используем эту инструкцию, чтобы возвратить значение функции, но куда же мы передаем 0, когда программа заканчивается? Ответ прост: мы возвращаем его операционной системе.

При запуске программы на языке Си можно считать, что операционная система вызывает функцию main(). Когда программа заканчивает выполнение, инструкция return() возвращает управление в систему. Параметр инструкции return() может, например, сообщать системе, имела ли место ошибка и что это была за ошибка. В этом случае запись return(0) сообщит, что ошибок не было. Некоторые программы могут возвращать и другие значения с тем, чтобы проинформировать операционную систему о возникших во время выполнения ошибках. В этом случае появится возможность выполнения дополнительных действий в зависимости от того, каким образом была прекращена работа программы*.

Использование макроопределений

Вы уже знаете, что, используя директиву #define, можно задавать константы. Например, если написать инструкцию #define PI 3.14, компилятор подставит значение3.14 на место всех встречающихся в программе констант PI.

Директива #define предписывает компилятору заменить имя константы на то, что следует за этим именем. Если после имени константы ввести какую-нибудь инструкцию, компилятор тоже произведет подстановку. Например, в следующей инструкции мы подставляем на место константы ENTER функцию printf():

#define ENTER printf("Пожалуйста, введите число: ")

Теперь, при необходимости отобразить сообщение, записанное в аргументе функции printf(), достаточно в соответствующем месте программы использовать инструкцию ENTER:

#define ENTER printf("Пожалуйста, введите число: ")

main()

{

int age, size;

ENTER;

scanf("%d", &age);

ENTER;

scanf("%d", &size);

}

Рис. 7.9. Использование макроопределения

При выполнении программы сообщение «Пожалуйста, введите число:» будет появляться на экране точно так же, как если бы в main() была полностью написана инструкция, содержащая функцию printf() (рис.7.9).

Директивы, подобные той, которую мы только что рассмотрели, называются макроопределениями или макросами*. Они являются очень мощным средством, позволяющим избежать необходимости вручную вводить одну и ту же инструкцию несколько раз в одной программе. Например, макрос ENTER можно использовать всякий раз, когда нужно подсказать пользователю, что он должен ввести данные. Еще более мощным программным средством макроопределения делает то обстоятельство, что им можно передавать аргументы, так же, как функциям. В приведенной ниже программе, например, макрос CONVERT используется для перевода значения температуры из шкалы Фаренгейта в шкалу Цельсия:

#define ENTER printf("Пожалуйста, введите значение температуры: ")

#define CONVERT(temp) (5.0 / 9.0) * (temp - 32)

main()

{

float climate;

ENTER;

scanf("%f", &climate);

printf("это соответствует %f по шкале Цельсия\n", CONVERT(climate));

}

Рис. 7.10. Определение выражения как макроса

Во второй директиве #define определяется макрос CONVERT, который требует передачи ему одного значения. Аргумент, принимаемый макросом CONVERT, подставляется в выражение (5.0 / 9.0) * (temp - 32) на место слова temp. Вызов макроса осуществляется способом, аналогичным вызову функции, с использованием в качестве аргумента значения, которое мы хотим преобразовать (рис.7.10). Если в ответ на запрос введено значение212, происходит вызов CONVERT в функции printf() и расчет значения выражения (5.0 / 9.0) * (212 - 32).

__________________________

* В литературе также используется термин макроподстановка. (Прим.перев.)

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