Главная » Просмотр файлов » B. Stroustrup - The C++ Programming Language

B. Stroustrup - The C++ Programming Language (794319), страница 56

Файл №794319 B. Stroustrup - The C++ Programming Language (B. Stroustrup - The C++ Programming Language) 56 страницаB. Stroustrup - The C++ Programming Language (794319) страница 562019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

In C++, an assignment is an expression, a function call is an expression, the construction of an object is an expression, and so are many otheroperations that go beyond conventional arithmetic expression evaluation. To give an impression ofhow expressions are used and to show them in context, I first present a small complete program, asimple ‘‘desk calculator.’’ Next, the complete set of operators is listed and their meaning for builtin types is briefly outlined.

The operators that require more extensive explanation are discussed inChapter 11.242ExpressionsChapter 1010.2 A Desk CalculatorConsider a simple desk calculator program that provides the four standard arithmetic operations asinfix operators on floating-point numbers. The user can also define variables. For example, giventhe inputr = 2.5area = pi ∗ r ∗ r(pi is predefined) the calculator program will write2.519.635where 2.5 is the result of the first line of input and 19.635 is the result of the second.The calculator consists of four main parts: a parser, an input function, a symbol table, and adriver.

Actually, it is a miniature compiler in which the parser does the syntactic analysis, the inputfunction handles input and lexical analysis, the symbol table holds permanent information, and thedriver handles initialization, output, and errors. We could add many features to this calculator tomake it more useful, but the code is long enough as it is, and most features would just add codewithout providing additional insight into the use of C++.10.2.1 The ParserHere is a grammar for the language accepted by the calculator:program:endexpr_list end// end is end-of-inputexpr_list:expression printexpression print expr_list// print is newline or semicolonexpression:expression + termexpression − termtermterm:term / primaryterm ∗ primaryprimaryprimary:numbernamename = expression− primary( expression )// number is a floating-point literal// name is an identifierSection 10.2.1The Parser243In other words, a program is a sequence of expressions separated by semicolons.

The basic units ofan expression are numbers, names, and the operators ∗, /, +, − (both unary and binary), and =(assignment). Names need not be declared before use.I use a style of syntax analysis called recursive descent; it is a popular and straightforward topdown technique. In a language such as C++, in which function calls are relatively cheap, it is alsoefficient. For each production in the grammar, there is a function that calls other functions. Terminal symbols (for example, end, number, +, and −) are recognized by a lexical analyzer and nonterminal symbols are recognized by the syntax analyzer functions, expr(), term(), and prim(). As soonas both operands of a (sub)expression are known, the expression is evaluated; in a real compiler,code could be generated at this point.For input, the parser uses a Token_stream that encapsulates the reading of characters and theircomposition into Tokens.

That is, a Token_stream ‘‘tokenizes’’: it turns streams of characters, suchas 123.45, into Tokens. A Token is a {kind-of-token,value} pair, such as {number,123.45}, where the123.45 has been turned into a floating point value. The main parts of the parser need only to knowthe name of the Token_stream, ts, and how to get Tokens from it. To read the next Token, it callsts.get(). To get the most recently read Token (the ‘‘current token’’), it calls ts.current(). In additionto providing tokenizing, the Token_stream hides the actual source of the characters.

We’ll see thatthey can come directly from a user typing to cin, from a program command line, or from any otherinput stream (§10.2.7).The definition of Token looks like this:enum class Kind : char {name, number, end,plus='+', minus='−', mul='∗', div='/’, print=';', assign='=', lp='(', rp=')'};struct Token {Kind kind;string string_value;double number_value;};Representing each token by the integer value of its character is convenient and efficient and can bea help to people using debuggers.

This works as long as no character used as input has a value usedas an enumerator – and no current character set I know of has a printing character with a singledigit integer value.The interface to Token_stream looks like this:class Token_stream {public:Token get();// read and return next tokenconst Token& current(); // most recently read token// ...};The implementation is presented in §10.2.2.Each parser function takes a bool (§6.2.2) argument, called get, indicating whether the functionneeds to call Token_stream::get() to get the next token. Each parser function evaluates ‘‘its’’244ExpressionsChapter 10expression and returns the value. The function expr() handles addition and subtraction. It consistsof a single loop that looks for terms to add or subtract:double expr(bool get){double left = term(get);// add and subtractfor (;;) {// ‘‘forever’’switch (ts.current().kind) {case Kind::plus:left += term(true);break;case Kind::minus:left −= term(true);break;default:return left;}}}This function really does not do much itself.

In a manner typical of higher-level functions in alarge program, it calls other functions to do the work.The switch-statement (§2.2.4, §9.4.2) tests the value of its condition, which is supplied in parentheses after the switch keyword, against a set of constants. The break-statements are used to exit theswitch-statement. If the value tested does not match any case label, the default is chosen.

The programmer need not provide a default.Note that an expression such as 2−3+4 is evaluated as (2−3)+4, as specified in the grammar.The curious notation for(;;) is a way to specify an infinite loop; you could pronounce it ‘‘forever’’ (§9.5); while(true) is an alternative. The switch-statement is executed repeatedly until something different from + and − is found, and then the return-statement in the default case is executed.The operators += and −= are used to handle the addition and subtraction; left=left+term(true) andleft=left−term(true) could have been used without changing the meaning of the program.

However,left+=term(true) and left−=term(true) are not only shorter but also express the intended operationdirectly. Each assignment operator is a separate lexical token, so a + = 1; is a syntax error becauseof the space between the + and the =.C++ provides assignment operators for the binary operators:+−∗/%&|ˆ<<>>so that the following assignment operators are possible:=+=−=∗=/=%= &=|=ˆ=<<= >>=The % is the modulo, or remainder, operator; &, |, and ˆ are the bitwise logical operators and, or, andexclusive or; << and >> are the left shift and right shift operators; §10.3 summarizes the operatorsand their meanings.

For a binary operator @ applied to operands of built-in types, an expressionx@=y means x=x@y, except that x is evaluated once only.Section 10.2.1The Parser245The function term() handles multiplication and division in the same way expr() handles additionand subtraction:double term(bool get){double left = prim(get);// multiply and dividefor (;;) {switch (ts.current().kind) {case Kind::mul:left ∗= prim(true);break;case Kind::div:if (auto d = prim(true)) {left /= d;break;}return error("divide by 0");default:return left;}}}The result of dividing by zero is undefined and usually disastrous.

We therefore test for 0 beforedividing and call error() if we detect a zero divisor. The function error() is described in §10.2.4.The variable d is introduced into the program exactly where it is needed and initialized immediately.

The scope of a name introduced in a condition is the statement controlled by that condition,and the resulting value is the value of the condition (§9.4.3). Consequently, the division andassignment left/=d are done if and only if d is nonzero.The function prim() handling a primary is much like expr() and term(), except that because we aregetting lower in the call hierarchy a bit of real work is being done and no loop is necessary:double prim(bool get)// handle primaries{if (get) ts.get(); // read next tokenswitch (ts.current().kind) {case Kind::number:// floating-point constant{double v = ts.current().number_value;ts.get();return v;}case Kind::name:{double& v = table[ts.current().string_value];if (ts.get().kind == Kind::assign) v = expr(true);return v;}// find the corresponding// ’=’ seen: assignment246ExpressionsChapter 10case Kind::minus:// unar y minusreturn −prim(true);case Kind::lp:{auto e = expr(true);if (ts.current().kind != Kind::rp) return error("')' expected");ts.get();// eat ’)’return e;}default:return error("primary expected");}}When a Token that is a number (that is, an integer or floating-point literal) is seen, its value is placedin its number_value.

Similarly, when a Token that is a name (however defined; see §10.2.2 and§10.2.3) is seen, its value is placed in its string_value.Note that prim() always reads one more Token than it uses to analyze its primary expression.The reason is that it must do that in some cases (e.g., to see if a name is assigned to), so for consistency it must do it in all cases. In the cases where a parser function simply wants to move ahead tothe next Token, it doesn’t use the return value from ts.get(). That’s fine because we can get theresult from ts.current(). Had ignoring the return value of get() bothered me, I’d have either added aread() function that just updated current() without returning a value or explicitly ‘‘thrown away’’ theresult: void(ts.get()).Before doing anything to a name, the calculator must first look ahead to see if it is beingassigned to or simply read.

In both cases, the symbol table is consulted. The symbol table is a map(§4.4.3, §31.4.3):map<string,double> table;That is, when table is indexed by a string, the resulting value is thestring. For example, if the user entersdoublecorresponding to theradius = 6378.388;the calculator will reach case Kind::name and executedouble& v = table["radius"];// ...

expr() calculates the value to be assigned ...v = 6378.388;The reference v is used to hold on to the double associated with radius while expr() calculates thevalue 6378.388 from the input characters.Chapter 14 and Chapter 15 discuss how to organize a program as a set of modules. However,with one exception, the declarations for this calculator example can be ordered so that everything isdeclared exactly once and before it is used. The exception is expr(), which calls term(), which callsprim(), which in turn calls expr().

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

Тип файла
PDF-файл
Размер
18,76 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

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