45940 (665245), страница 7

Файл №665245 45940 (Язык С) 7 страница45940 (665245) страница 72016-07-31СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 7)

ется расширением ато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;

  • 78 -

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(...) являются плавающие числа двойной точности.

  • 79 -

Если функция 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 осуществляется посредством отбрасывания

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

Упражнение 4-2.

Расширьте ATOF таким образом, чтобы она могла работать с

числами вида

123.45е-6

где за числом с плавающей точкой может следовать 'E' и пока-

затель экспоненты, возможно со знаком.

4.3. Еще об аргументах функций.

В главе 1 мы уже обсуждали тот факт , что аргументы фун-

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

свою временную копию каждого аргумента, а не его адрес. это

означает, что вызванная функция не может воздействовать на

исходный аргумент в вызывающей функции. Внутри функции каж-

дый аргумент по существу является локальной переменной, ко-

торая инициализируется тем значением, с которым к этой функ-

ции обратились.

  • 80 -

Если в качестве аргумента функции выступает имя массива,

то передается адрес начала этого массива; сами элементы не

копируются. Функция может изменять элементы массива, исполь-

зуя индексацию и адрес начала. Таким образом, массив переда-

ется по ссылке. В главе 5 мы обсудим, как использование ука-

зателей позволяет функциям воздействовать на отличные от

массивов переменные в вызывающих функциях.

Между прочим, несуществует полностью удовлетворительного

способа написания переносимой функции с переменным числом

аргументов. Дело в том, что нет переносимого способа, с по-

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

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

нии. Таким образом, вы, например, не можете написать дейст-

вительно переносимую функцию, которая будет вычислять макси-

мум от произвольного числа аргументов, как делают встроенные

функции MAX в фортране и PL/1.

Обычно со случаем переменного числа аргументов безопасно

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

которые ей на самом деле не были переданы, и если типы сог-

ласуются. Самая распространенная в языке “C” функция с пере-

менным числом - PRINTF . Она получает из первого аргумента

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

гументов и их типы. Функция PRINTF работает совершенно неп-

равильно, если вызывающая функция передает ей недостаточное

количество аргументов, или если их типы не согласуются с ти-

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

переносимой и должна модифицироваться при использовании в

различных условиях.

Если же типы аргументов известны, то конец списка аргу-

ментов можно отметить, используя какое-то соглашение; напри-

мер, считая, что некоторое специальное значение аргумента

(часто нуль) является признаком конца аргументов.

4.4. Внешние переменные.

Программа на языке “C” состоит из набора внешних объек-

тов, которые являются либо переменными, либо функциями. Тер-

мин “внешний” используется главным образом в противопостав-

ление термину “внутренний”, которым описываются аргументы и

автоматические переменные, определенные внурти функций.

Внешние переменные определены вне какой-либо функции и, та-

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

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

“C” не разрешают определять одни функции внутри других. По

умолчанию внешние переменные являются также и “глобальными”,

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

то же имя (даже из функций, скомпилированных независимо),

будут ссылками на одно и то же. В этом смысле внешние пере-

менные аналогичны переменным COмMON в фортране и EXTERNAL в

PL/1. Позднее мы покажем, как определить внешние переменные

и функции таким образом, чтобы они были доступны не глобаль-

но, а только в пределах одного исходного файла.

  • 81 -

В силу своей глобальной доступности внешние переменные

предоставляют другую, отличную от аргументов и возвращаемых

значений, возможность для обмена данными между функциями.

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

любая функция имеет доступ к этой переменной, ссылаясь к ней

по этому имени.

В случаях, когда связь между функциями осуществляется с

помощью большого числа переменных, внешние переменные оказы-

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

длинных списков аргументов. Как, однако, отмечалось в главе

1, это соображение следует использовать с определенной осто-

рожностью, так как оно может плохо отразиться на структуре

программ и приводить к программам с большим числом связей по

данным между функциями.

Вторая причина использования внешних переменных связана

с инициализацией. В частности, внешние массивы могут быть

инициализированы а автоматические нет. Мы рассмотрим вопрос

об инициализации в конце этой главы.

Третья причина использования внешних переменных обуслов-

лена их областью действия и временем существования. Автома-

тические переменные являются внутренними по отношению к фун-

кциям; они возникают при входе в функцию и исчезают при вы-

ходе из нее. Внешние переменные, напротив, существуют посто-

янно. Они не появляютя и не исчезают, так что могут сохра-

нять свои значения в период от одного обращения к функции до

другого. В силу этого, если две функции используют некоторые

общие данные, причем ни одна из них не обращается к другой ,

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

ные в виде внешних переменных, а не передавать их в функцию

и обратно с помощью аргументов.

Давайте продолжим обсуждение этого вопроса на большом

примере. Задача будет состоять в написании другой программы

для калькулятора, лучшей,чем предыдущая. Здесь допускаются

операции +,-,*,/ и знак = (для выдачи ответа).вместо инфикс-

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

польскую нотацию,поскольку ее несколько легче реализовать.в

обратной польской нотации знак следует за операндами; инфик-

сное выражение типа

(1-2)*(4+5)=

записывается в виде

12-45+*=

круглые скобки при этом не нужны

  • 82 -

Реализация оказывается весьма простой.каждый операнд по-

мещается в стек; когда поступает знак операции,нужное число

операндов (два для бинарных операций) вынимается,к ним при-

меняется операция и результат направляется обратно в

стек.так в приведенном выше примере 1 и 2 помещаются в стек

и затем заменяются их разностью, -1.после этого 4 и 5 вво-

дятся в стек и затем заменяются своей суммой,9.далее числа

  • 1 и 9 заменяются в стеке на их произведение,равное -9.опе-рация = печатает верхний элемент стека, не удаляя его (так что промежуточные вычисления могут быть проверены).

Сами операции помещения чисел в стек и их извлечения

очень просты,но, в связи с включением в настоящую программу

обнаружения ошибок и восстановления,они оказываются доста-

точно длинными. Поэтому лучше оформить их в виде отдельных

функций,чем повторять соответствующий текст повсюду в прог-

рамме. Кроме того, нужна отдельная функция для выборки из

ввода следующей операции или операнда. Таким образом, струк-

тура программы имеет вид:

WHILE( поступает операция или операнд, а не конец

IF ( число )

поместить его в стек

еLSE IF ( операция )

вынуть операнды из стека

выполнить операцию

поместить результат в стек

ELSE

ошибка

Основной вопрос, который еще не был обсужден, заключает-

ся в том,где поместить стек, т. Е. Какие процедуры смогут

обращаться к нему непосредственно. Одна из таких возможнос-

тей состоит в помещении стека в MAIN и передачи самого стека

и текущей позиции в стеке функциям, работающим со стеком. Но

функции MAIN нет необходимости иметь дело с переменными, уп-

равляющими стеком; ей естественно рассуждать в терминах по-

мещения чисел в стек и извлечения их оттуда. В силу этого мы

решили сделать стек и связанную с ним информацию внешними

переменными , доступными функциям PUSH (помещение в стек) и

POP (извлечение из стека), но не MAIN.

Перевод этой схемы в программу достаточно прост. Ведущая

программа является по существу большим переключателем по ти-

пу операции или операнду; это, по-видимому, более характер-

ное применеие переключателя, чем то, которое было продемонс-

трировано в главе 3.

#DEFINE MAXOP 20 /* MAX SIZE OF OPERAND, OPERАTOR *

#DEFINE NUMBER '0' /* SIGNAL THAT NUMBER FOUND */

#DEFINE TOOBIG '9' /* SIGNAL THAT STRING IS TOO BIG *

  • 83 -

MAIN() /* REVERSE POLISH DESK CALCULATOR */

/(

INT TUPE;

CHAR S[MAXOP];

DOUBLE OP2,ATOF(),POP(),PUSH();

WHILE ((TUPE=GETOP(S,MAXOP)) !=EOF);

SWITCH(TUPE) /(

CASE NUMBER:

PUSH(ATOF(S));

BREAK;

CASE '+':

PUSH(POP()+POP());

Характеристики

Тип файла
Документ
Размер
2,35 Mb
Материал
Тип материала
Учебное заведение
Неизвестно

Список файлов реферата

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6518
Авторов
на СтудИзбе
302
Средний доход
с одного платного файла
Обучение Подробнее