Чтение онлайн

на главную - закладки

Жанры

Язык программирования Си. Издание 3-е, исправленное

Ритчи Деннис М.

Шрифт:

power *= 10.0;

 }

 return sign * val / power;

}

Кроме того, важно, чтобы вызывающая программа знала, что atof возвращает нецелое значение. Один из способов обеспечить это - явно описать atof в вызывающей программе. Подобное описание демонстрируется ниже в программе простенького калькулятора (достаточного для проверки баланса чековой книжки), который каждую вводимую строку воспринимает как число, прибавляет его к текущей сумме и печатает ее новое значение.

#include ‹stdio.h›

#define MAXLINE 100

/*
примитивный калькулятор */

main

{

 double sum, atof (char[]);

 char line[MAXLINE];

 int getline (char line[], int max);

 sum = 0;

 while (getline(line, MAXLINE) › 0)

printf ("\t%g\n", sum += atof(line));

 return 0;

}

В объявлении

double sum, atof (char[]);

говорится, что sum– переменная типа double, a atof– функция, которая принимает один аргумент типа char[] и возвращает результат типа double.

Объявление и определение функции atof должны соответствовать друг другу. Если в одном исходном файле сама функция atof и обращение к ней в main имеют разные типы, то это несоответствие будет зафиксировано компилятором как ошибка. Но если функция atof была скомпилирована отдельно (что более вероятно), то несоответствие типов не будет обнаружено, и atof возвратит значение типа double, которое функция main воспримет как int, что приведет к бессмысленному результату.

Это последнее утверждение, вероятно, вызовет у вас удивление, поскольку ранее говорилось о необходимости соответствия объявлений и определений. Причина несоответствия, возможно, будет следствием того, что вообще отсутствует прототип функции, и функция неявно объявляется при первом своем появлении в выражении, как, например, в

sum += atof(line);

Если в выражении встретилось имя, нигде ранее не объявленное, за которым следует открывающая скобка, то такое имя по контексту считается именем функции, возвращающей результат типа int; при этом относительно ее аргументов ничего не предполагается. Если в объявлении функции аргументы не указаны, как в

double atof;

то и в этом случае считается, что ничего об аргументах atof не известно, и все проверки на соответствие ее параметров будут выключены. Предполагается, что такая специальная интерпретация пустого списка позволит новым компиляторам транслировать старые Си-программы. Но в новых программах пользоваться этим - не очень хорошая идея. Если у функции есть аргументы, опишите их, если их нет, используйте слово void.

Располагая соответствующим образом описанной функцией atof, мы можем написать функцию atoi, преобразующую строку символов в целое значение, следующим образом:

/* atoi: преобразование строки s в int с помощью atof */

int atoi (char s[])

{

 double atof (char s[]);

 return (int) atof (s);

}

Обратите внимание

на вид объявления и инструкции return. Значение выражения в

return выражение;

перед тем, как оно будет возвращено в качестве результата, приводится к типу функции. Следовательно, поскольку функция atoi возвращает значение int, результат вычисления atof типа double в инструкции return автоматически преобразуется в тип int. При преобразовании возможна потеря информации, и некоторые компиляторы предупреждают об этом. Оператор приведения явно указывает на необходимость преобразования типа и подавляет любое предупреждающее сообщение.

Упражнение 4.2. Дополните функцию atof таким образом, чтобы она справлялась с числами вида

123.45e-6

в которых после мантиссы может стоять e (или E) с последующим порядком (быть может, со знаком).

4.3 Внешние переменные

Программа на Си обычно оперирует с множеством внешних объектов: переменных и функций. Прилагательное "внешний" (external) противоположно прилагательному "внутренний", которое относится к аргументам и переменным, определяемым внутри функций. Внешние переменные определяются вне функций и потенциально доступны для многих функций. Сами функции всегда являются внешними объектами, поскольку в Си запрещено определять функции внутри других функций. По умолчанию одинаковые внешние имена, используемые в разных файлах, относятся к одному и тому же внешнему объекту (функции). (В стандарте это называется редактированием внешних связей (линкованием) (external linkage).) В этом смысле внешние переменные похожи на области COMMON в Фортране и на переменные самого внешнего блока в Паскале. Позже мы покажем, как внешние функции и переменные сделать видимыми только внутри одного исходного файла.

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

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

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

В связи с приведенными рассуждениями разберем пример. Поставим себе задачу написать программу-калькулятор, понимающую операторы +, -, * и /. Такой калькулятор легче будет написать, если ориентироваться на польскую, а не инфиксную запись выражений. (Обратная польская запись применяется в некоторых карманных калькуляторах и в таких языках, как Forth и Postscript.) В обратной польской записи каждый оператор следует за своими операндами. Выражение в инфиксной записи, скажем

(1 - 2) * (4 + 5)

Поделиться:
Популярные книги

Усадьба леди Анны

Ром Полина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Усадьба леди Анны

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Двойник Короля

Скабер Артемий
1. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Двойник Короля

Его нежеланная истинная

Кушкина Милена
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Его нежеланная истинная

Последний Паладин. Том 2

Саваровский Роман
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 2

Измена. Наследник для дракона

Солт Елена
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Измена. Наследник для дракона

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Мастер темных Арканов

Карелин Сергей Витальевич
1. Мастер темных арканов
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Мастер темных Арканов

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Вечный. Книга II

Рокотов Алексей
2. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга II

Законы Рода. Том 3

Flow Ascold
3. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 3

Наследник

Шимохин Дмитрий
1. Старицкий
Приключения:
исторические приключения
5.00
рейтинг книги
Наследник