Форум программистов, компьютерный форум CyberForum.ru

Как вычисляется выражение a+++b? - C++

Восстановить пароль Регистрация
 
tolik89u
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 11:54     Как вычисляется выражение a+++b? #1
Здравствуйте.
Как вычисляется выражение a+++b?
Как компилятор понимает, что означает +++: ++ + или + ++? Как он разбивает последовательность из трёх плюсов на два оператора? Есть понятия приоритета операций и ассоциативности, но они применяются уже к определённым операторам. А в данном случае как компилятор понимает, какой оператор использовался?

Добавлено через 2 минуты
Следующий код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void main(void){
    int a,b,c;
    a=10,b=100,c=1000;
    printf("a=10,b=100,c=1000;\na=%d, b=%d, c=%d\n\n",a,b,c);
    c=a+++b;
    printf("c=a+++b;\na=%d, b=%d, c=%d\n\n",a,b,c);
 
    a=10,b=100,c=1000;
    printf("a=10,b=100,c=1000;\na=%d, b=%d, c=%d\n\n",a,b,c);
    c=(a++)+b;
    printf("c=(a++)+b;\na=%d, b=%d, c=%d\n\n",a,b,c);
 
    a=10,b=100,c=1000;
    printf("a=10,b=100,c=1000;\na=%d, b=%d, c=%d\n\n",a,b,c);
    c=a+(++b);
    printf("c=a+(++b);\na=%d, b=%d, c=%d\n\n",a,b,c);
}
я выполнил в онлайн-компиляторе C: http://codepad.org/CtpEfoHy
Вот вывод программы:
Код
a=10,b=100,c=1000;
a=10, b=100, c=1000

c=a+++b;
a=11, b=100, c=110

a=10,b=100,c=1000;
a=10, b=100, c=1000

c=(a++)+b;
a=11, b=100, c=110

a=10,b=100,c=1000;
a=10, b=100, c=1000
Из данного кода ясно, что данный компилятор воспринимает +++ как ++ +. Но объясните: почему? Чем он руководствуется? Оговорено ли это в стандарте C? Или это поведение меняется от компилятора к компилятору?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Тамика
Котовчанин
 Аватар для Тамика
859 / 439 / 129
Регистрация: 16.02.2010
Сообщений: 2,537
Записей в блоге: 27
28.05.2014, 11:55     Как вычисляется выражение a+++b? #2
C++
1
(a++) + b
.
tolik89u
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 11:57  [ТС]     Как вычисляется выражение a+++b? #3
Тамика, под моими словами: «Как компилятор понимает, какой оператор использовался»*— я подразумевал не просто: «Какой оператор использовался?»*— а: «Почему компилятор использовал тот или иной оператор?»
Тамика
Котовчанин
 Аватар для Тамика
859 / 439 / 129
Регистрация: 16.02.2010
Сообщений: 2,537
Записей в блоге: 27
28.05.2014, 12:02     Как вычисляется выражение a+++b? #4
Читая слева направо. Так же, как и человек видит простые примеры. Так как никаких скобок нет, то он воспринимает всё именно так. Видит, что есть переменна, видит два плюса. Всё. На три плюса никаких обработок нет. Потому берет выражение (а++) и обрабатывает его. Но остался еще +b. Потому результат (а++) суммируется с b. Не знаю как Вам ещё это объяснить. Более подробно может расскажут остальные. С удовольствием почитаю.
tolik89u
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 12:08  [ТС]     Как вычисляется выражение a+++b? #5
Цитата Сообщение от Тамика Посмотреть сообщение
Более подробно может расскажут остальные. С удовольствием почитаю.
Да, я тоже! Особенно интересно: как должен поступить компилятор согласно стандарта C. Или же это поведение оставлено на волю создателей компилятора и в стандарте не прописано?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11815 / 6794 / 769
Регистрация: 27.09.2012
Сообщений: 16,862
Записей в блоге: 2
Завершенные тесты: 1
28.05.2014, 12:14     Как вычисляется выражение a+++b? #6
Цитата Сообщение от Стефан К. Дьюхэрст "Скользкие места C++"
Добро пожаловать в мир "больших кусков". На одной из ранних стадий трансляции программы на C++ работает так называемый "лексический анализатор", задача которого, разбить входной поток на отдельные лексические единицы или лексемы. Встретив последовательность символов типа ->*, лексический анализатор может выделить три лексемы (-,> и *), две лексемы (-> и *) или одну лексему (->*), и все это будет разумно. Чтобы избежать неоднозначности, анализатор всегда выделяет самую длинную из возможных лексем: "максимальный кусок".
вот так
tolik89u
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 12:17  [ТС]     Как вычисляется выражение a+++b? #7
Croessmah, это уже близко.
Но всё-таки как ни понимай +++: либо ++ +, либо + ++, всё равно получается один двухплюсовый кусок и один одноплюсовый. Ни в одном из двух вариантов куски не больше второго. Куски одинаковые, просто местами меняются. Может, имеется в виду, что «левосторонние» лексические анализаторы ищут большие куски слева?
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,307
28.05.2014, 12:48     Как вычисляется выражение a+++b? #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Такое поведение компилятора жестко определено Стандартом: например, [C99, 6.4/4] или [C++11, 2.5/3].
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
28.05.2014, 13:02     Как вычисляется выражение a+++b? #9
Цитата Сообщение от tolik89u Посмотреть сообщение
Здравствуйте.
Как вычисляется выражение a+++b?
Как компилятор понимает, что означает +++: ++ + или + ++? Как он разбивает последовательность из трёх плюсов на два оператора? Есть понятия приоритета операций и ассоциативности, но они применяются уже к определённым операторам. А в данном случае как компилятор понимает, какой оператор использовался?
Согласно жадному алгоритму, в первый из двух операторов попадёт максимально возможное количество символов, получится
C++
1
(a++)+b
. Но я бы поставил скобки, чтоб избавиться от необходимости учитывать алгоритмы трансляции.

Добавлено через 52 секунды
Цитата Сообщение от tolik89u Посмотреть сообщение
«Почему компилятор использовал тот или иной оператор?»
Потому что жадина.

Добавлено через 3 минуты
Цитата Сообщение от Тамика Посмотреть сообщение
итая слева направо. Так же, как и человек видит простые примеры.
Нет. Человек в этом месте видит:
1.
C++
1
a+++b
, где +++ - один оператор.
2.
C++
1
(a+)+(+b)
.
3.
C++
1
(a++)+b)
.
4.
C++
1
a+(++b)
.
И выбирает, опираясь на знания языка (отбрасывая первые два варианта) и алгоритма трансляции, анализируя фрагмент за компилятор. Компилятор же сразу принимает третий вариант.

Добавлено через 4 минуты
Цитата Сообщение от tolik89u Посмотреть сообщение
Но всё-таки как ни понимай +++: либо ++ +, либо + ++, всё равно получается один двухплюсовый кусок и один одноплюсовый. Ни в одном из двух вариантов куски не больше второго.
Не надо сравнивать сумму, или среднее кусков, важно, где больше первый кусок.
Тамика
Котовчанин
 Аватар для Тамика
859 / 439 / 129
Регистрация: 16.02.2010
Сообщений: 2,537
Записей в блоге: 27
28.05.2014, 13:04     Как вычисляется выражение a+++b? #10
Цитата Сообщение от taras atavin Посмотреть сообщение
Нет. Человек в этом месте видит:
Я говорила о ПРОСТЫХ примерах и речь шла о направлении "чтения" выражения. Если я напишу а+б, разве Вы увидите в этом +аб или ба+ ? Нет. Увидите слева направо а+б. А потом уже описывала, что будет дальше.
tolik89u
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 13:08  [ТС]     Как вычисляется выражение a+++b? #11
Цитата Сообщение от CheshireCat Посмотреть сообщение
Такое поведение компилятора жестко определено Стандартом: например, [C99, 6.4/4] или [C++11, 2.5/3].
Спасибо! Чётко и по существу! Меня больше интересовал чистый C, поэтому я ограничился прочтением первой ссылки. Для всех интересующихся — вот что там сказано:
Цитата Сообщение от C99, 6.4/4-6
4 If the input stream has been parsed into preprocessing tokens up to a given character, the
next preprocessing token is the longest sequence of characters that could constitute a
preprocessing token. There is one exception to this rule: header name preprocessing
tokens are recognized only within #include preprocessing directives and in
implementation-defined locations within #pragma directives. In such contexts, a
sequence of characters that could be either a header name or a string literal is recognized
as the former.
5 EXAMPLE 1 The program fragment 1Ex is parsed as a preprocessing number token (one that is not a
valid floating or integer constant token), even though a parse as the pair of preprocessing tokens 1 and Ex
might produce a valid expression (for example, if Ex were a macro defined as +1). Similarly, the program
fragment 1E1 is parsed as a preprocessing number (one that is a valid floating constant token), whether or
not E is a macro name.
6 EXAMPLE 2 The program fragment x+++++y is parsed as x ++ ++ + y, which violates a constraint on
increment operators, even though the parse x ++ + ++ y might yield a correct expression.
В частности, в параграфе 6 чётко прописано пояснение на примере, разъясняющем конкретно мой случай.
Ещё раз убеждаюсь в истинности одного изречения, с которым меня давно ознакомил один админ. В этом изречении сокрыта вековая мудрость программистов-предков:
Читайте маны: они — рулёз!
Спасибо, CheshireCat!
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
28.05.2014, 13:11     Как вычисляется выражение a+++b? #12
Цитата Сообщение от Тамика Посмотреть сообщение
Вы увидите в этом +аб или ба+ ? Нет.
Ну как где у меня + перенесён через операнд? И не путай случай единичного оператора-символа с последовательсностью символов, даже в примере a++b сначала человек видит:
1. a++b, где ++ - единый бинарный оператор,
2. (a+)(+b), где между опендами-результатами вообще нет оператора, а оба имеющихся оператора унарны, причём, первый ещё и постфиксный.
3. (a+)+b, где только второй плюс бинарный, а первый - унарный и постфиксный.
4. a+(+b), где только первый плюс бинарный, а второй - унарный и префиксный.
И только потом говорит: "Бредятина".
SatanaXIII
28.05.2014, 13:11
  #13

Не по теме:

Хорошо, что тс не спросил еще про a+++++b.

tolik89u
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 13:14  [ТС]     Как вычисляется выражение a+++b? #14
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Хорошо, что тс не спросил еще про a+++++b.
А вот "a+++++b", как сказано в цитате стандарта выше, не вычисляется. Хотя можно было бы и так вопрос поставить, конечно. Главное*— теперь я узнал этот новый для меня принцип, который taras atavin назвал «жадным алгоритмом».
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
28.05.2014, 13:20     Как вычисляется выражение a+++b? #15
Жадина из этого сделает
C++
1
((a++)++)+b
. Не вычисляется из-за того, что инкремент не инкермируется? А можно было бы вычислить, если разбить иначе, например,
C++
1
(a++)+(++b)
. Но так c++ не копмилит.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.05.2014, 13:25     Как вычисляется выражение a+++b?
Еще ссылки по теме:

C++ Прототип функции. Площадь не вычисляется
Не вычисляется уравнение C++
Не вычисляется сумма ряда C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
tolik89u
28.05.2014, 13:25  [ТС]     Как вычисляется выражение a+++b?
  #16

Не по теме:

Цитата Сообщение от taras atavin Посмотреть сообщение
Ну как где у меня + перенесён через операнд? И не путай случай единичного оператора-символа с последовательсностью символов, даже в примере a++b сначала человек видит:
1. a++b, где ++ - единый бинарный оператор,
2. (a+)(+b), где между опендами-результатами вообще нет оператора, а оба имеющихся оператора унарны, причём, первый ещё и постфиксный.
3. (a+)+b, где только второй плюс бинарный, а первый - унарный и постфиксный.
4. a+(+b), где только первый плюс бинарный, а второй - унарный и префиксный.
И только потом говорит: "Бредятина".
Вы пропустили ещё (a++)(b) и (a)(++b)

Yandex
Объявления
28.05.2014, 13:25     Как вычисляется выражение a+++b?
Ответ Создать тему
Опции темы

Текущее время: 14:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru