Главная Случайная страница


Полезное:

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


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Функции, возвращающие нецелые значения





 

До сих пор ни одна из наших программ не содержала како-

го-либо описания типа функции. Дело в том, что по умолчанию

функция неявно описывается своим появлением в выражении или

операторе, как, например, в

 

WHILE (GETLINE(LINE, MAXLINE) > 0)

 

Если некоторое имя, которое не было описано ранее, появ-

ляется в выражении и за ним следует левая круглая скобка, то

оно по контексту считается именем некоторой функции. Кроме

того, по умолчанию предполагается, что эта функция возвраща-

ет значение типа INT. Так как в выражениях CHAR преобразует-

ся в INT, то нет необходимости описывать функции, возвращаю-

щие CHAR. Эти предположения покрывают большинство случаев,

включая все приведенные до сих пор примеры.

Но что происходит, если функция должна возвратить значе-

ние какого-то другого типа? Многие численные функции, такие

как SQRT, SIN и COS возвращают DOUBLE; другие специальные

функции возвращают значения других типов. Чтобы показать,

как поступать в этом случае, давайте напишем и используем

функцию ATоF(S), которая преобразует строку S в эквивалент-

ное ей плавающее число двойной точности. Функция ATоF явля-

ется расширением атоI, варианты которой мы написали в главах

2 и 3; она обрабатывает необязательно знак и десятичную точ-

ку, а также целую и дробную часть, каждая из которых может

как присутствовать, так и отсутствовать./эта процедура пре-

образования ввода не очень высокого качества; иначе она бы

заняла больше места, чем нам хотелось бы/.

Во-первых, сама ATоF должна описывать тип возвращаемого

ею значения, поскольку он отличен от INT. Так как в выраже-

ниях тип FLOAT преобразуется в DOUBLE, то нет никакого смыс-

ла в том, чтобы ATOF возвращала FLOAT; мы можем с равным ус-

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

полагаем, что возвращаемое значение типа DOUBLE. Имя типа

должно стоять перед именем функции, как показывается ниже:

 

DOUBLE ATOF(S) /* CONVERT STRING S TO DOUBLE */

CHAR S[];

{

DOUBLE VAL, POWER;

INT I, SIGN;

 

FOR(I=0; S[I]==' ' \!\! S[I]=='\N' \!\! S[I]=='\T'; I++)

; /* SKIP WHITE SPACE */

SIGN = 1;

IF (S[I] == '+' \!\! S[I] == '-') /* SIGN */

SIGN = (S[I++] == '+')? 1: -1;

FOR (VAL = 0; S[I] >= '0' && S[I] <= '9'; I++)

VAL = 10 * VAL + S[I] - '0';

IF (S[I] == '.')

I++;

FOR (POWER = 1; S[I] >= '0' && S[I] <= '9'; I++) {

VAL = 10 * VAL + S[I] - '0';

POWER *= 10;

}

RETURN(SIGN * VAL / POWER);

}

 

Вторым, но столь же важным, является то, что вызывающая

функция должна объявить о том, что ATOF возвращает значение,

отличное от INT типа. Такое объявление демонстрируется на

примере следующего примитивного настольного калькулятора

/едва пригодного для подведения баланса в чековой книжке/,

который считывает по одному числу на строку, причем это чис-

ло может иметь знак, и складывает все числа, печатая сумму

после каждого ввода.

 

#DEFINE MAXLINE 100

MAIN() /* RUDIMENTARY DESK CALKULATOR */

{

DOUBLE SUM, ATOF();

CHAR LINE[MAXLINE];

 

SUM = 0;

WHILE (GETLINE(LINE, MAXLINE) > 0)

PRINTF("\T%.2F\N",SUM+=ATOF(LINE));

 

 

Оисание

 

DOUBLE SUM, ATOF();

 

 

говорит, что SUM является переменной типа DOUBLE, и что

ATOF является функцией, возвращающей значение типа DOUBLE.

Эта мнемоника означает, что значениями как SUM, так и

ATOF(...) являются плавающие числа двойной точности.

 

Если функция ATOF не будет описана явно в обоих местах,

то в "C" предполагается, что она возвращает целое значение,

и вы получите бессмысленный ответ. Если сама ATOF и обраще-

ние к ней в MAIN имеют несовместимые типы и находятся в од-

ном и том же файле, то это будет обнаружено компилятором. Но

если ATOF была скомпилирована отдельно /что более вероятно/,

то это несоответствие не будет зафиксировано, так что ATOF

будет возвращать значения типа DOUBLE, с которым MAIN будет

обращаться, как с INT, что приведет к бессмысленным резуль-

татам. /Программа LINT вылавливает эту ошибку/.

Имея ATOF, мы, в принципе, могли бы с ее помощью напи-

сать ATOI (преобразование строки в INT):

 

ATOI(S) /* CONVERT STRING S TO INTEGER */

CHAR S[];

{

DOUBLE ATOF();

 

RETURN(ATOF(S));

}

 

 

Обратите внимание на структуру описаний и оператор RETURN.

Значение выражения в

 

RETURN (выражение)

 

всегда преобразуется к типу функции перед выполнением самого

возвращения. Поэтому при появлении в операторе RETURN значе-

ние функции атоF, имеющее тип DOUBLE, автоматически преобра-

зуется в INT, поскольку функция ATOI возвращает INT. (Как

обсуждалось в главе 2, преобразование значения с плавающей

точкой к типу INT осуществляется посредством отбрасывания

дробной части).

 







Date: 2015-09-17; view: 357; Нарушение авторских прав



mydocx.ru - 2015-2024 year. (0.008 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию