Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.68/65: Рейтинг темы: голосов - 65, средняя оценка - 4.68
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
1

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

28.05.2014, 11:54. Показов 12117. Ответов 15
Метки нет (Все метки)

Здравствуйте.
Как вычисляется выражение 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? Или это поведение меняется от компилятора к компилятору?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.05.2014, 11:54
Ответы с готовыми решениями:

Как вычисляется выражение
Как вычисляется выражение while? char *str1; char *str2; ... while(*str2++ = *str1++); ...

Неверно вычисляется выражение
Не до конца сделал программу.Суть в том в "sbichne" выводиться 0 в любом случае.До некоторых...

Неправильно вычисляется логическое выражение
В этом отрывке программы у меня программа не замечает условие,почему? То есть она выводит не для...

Не вычисляется выражение при отрицательных значениях
Делаю лабу и тут возникла проблема, программа не считает выражение при отрицательных переменных,...

15
Котовчанин
940 / 480 / 200
Регистрация: 16.02.2010
Сообщений: 3,338
Записей в блоге: 37
28.05.2014, 11:55 2
C++
1
(a++) + b
.
0
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 11:57  [ТС] 3
Тамика, под моими словами: «Как компилятор понимает, какой оператор использовался»*— я подразумевал не просто: «Какой оператор использовался?»*— а: «Почему компилятор использовал тот или иной оператор?»
0
Котовчанин
940 / 480 / 200
Регистрация: 16.02.2010
Сообщений: 3,338
Записей в блоге: 37
28.05.2014, 12:02 4
Читая слева направо. Так же, как и человек видит простые примеры. Так как никаких скобок нет, то он воспринимает всё именно так. Видит, что есть переменна, видит два плюса. Всё. На три плюса никаких обработок нет. Потому берет выражение (а++) и обрабатывает его. Но остался еще +b. Потому результат (а++) суммируется с b. Не знаю как Вам ещё это объяснить. Более подробно может расскажут остальные. С удовольствием почитаю.
0
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 12:08  [ТС] 5
Цитата Сообщение от Тамика Посмотреть сообщение
Более подробно может расскажут остальные. С удовольствием почитаю.
Да, я тоже! Особенно интересно: как должен поступить компилятор согласно стандарта C. Или же это поведение оставлено на волю создателей компилятора и в стандарте не прописано?
0
Don't worry, be happy
17252 / 10120 / 1959
Регистрация: 27.09.2012
Сообщений: 25,323
Записей в блоге: 1
28.05.2014, 12:14 6
Цитата Сообщение от Стефан К. Дьюхэрст "Скользкие места C++"
Добро пожаловать в мир "больших кусков". На одной из ранних стадий трансляции программы на C++ работает так называемый "лексический анализатор", задача которого, разбить входной поток на отдельные лексические единицы или лексемы. Встретив последовательность символов типа ->*, лексический анализатор может выделить три лексемы (-,> и *), две лексемы (-> и *) или одну лексему (->*), и все это будет разумно. Чтобы избежать неоднозначности, анализатор всегда выделяет самую длинную из возможных лексем: "максимальный кусок".
вот так
1
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 12:17  [ТС] 7
Croessmah, это уже близко.
Но всё-таки как ни понимай +++: либо ++ +, либо + ++, всё равно получается один двухплюсовый кусок и один одноплюсовый. Ни в одном из двух вариантов куски не больше второго. Куски одинаковые, просто местами меняются. Может, имеется в виду, что «левосторонние» лексические анализаторы ищут большие куски слева?
0
Эксперт С++
2922 / 1271 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
28.05.2014, 12:48 8
Лучший ответ Сообщение было отмечено tolik89u как решение

Решение

Такое поведение компилятора жестко определено Стандартом: например, [C99, 6.4/4] или [C++11, 2.5/3].
1
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
28.05.2014, 13:02 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 Посмотреть сообщение
Но всё-таки как ни понимай +++: либо ++ +, либо + ++, всё равно получается один двухплюсовый кусок и один одноплюсовый. Ни в одном из двух вариантов куски не больше второго.
Не надо сравнивать сумму, или среднее кусков, важно, где больше первый кусок.
1
Котовчанин
940 / 480 / 200
Регистрация: 16.02.2010
Сообщений: 3,338
Записей в блоге: 37
28.05.2014, 13:04 10
Цитата Сообщение от taras atavin Посмотреть сообщение
Нет. Человек в этом месте видит:
Я говорила о ПРОСТЫХ примерах и речь шла о направлении "чтения" выражения. Если я напишу а+б, разве Вы увидите в этом +аб или ба+ ? Нет. Увидите слева направо а+б. А потом уже описывала, что будет дальше.
0
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 13:08  [ТС] 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!
0
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
28.05.2014, 13:11 12
Цитата Сообщение от Тамика Посмотреть сообщение
Вы увидите в этом +аб или ба+ ? Нет.
Ну как где у меня + перенесён через операнд? И не путай случай единичного оператора-символа с последовательсностью символов, даже в примере a++b сначала человек видит:
1. a++b, где ++ - единый бинарный оператор,
2. (a+)(+b), где между опендами-результатами вообще нет оператора, а оба имеющихся оператора унарны, причём, первый ещё и постфиксный.
3. (a+)+b, где только второй плюс бинарный, а первый - унарный и постфиксный.
4. a+(+b), где только первый плюс бинарный, а второй - унарный и префиксный.
И только потом говорит: "Бредятина".
0
SatanaXIII
28.05.2014, 13:11
  #13

Не по теме:

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

0
157 / 2 / 0
Регистрация: 27.06.2013
Сообщений: 21
28.05.2014, 13:14  [ТС] 14
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Хорошо, что тс не спросил еще про a+++++b.
А вот "a+++++b", как сказано в цитате стандарта выше, не вычисляется. Хотя можно было бы и так вопрос поставить, конечно. Главное*— теперь я узнал этот новый для меня принцип, который taras atavin назвал «жадным алгоритмом».
0
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
28.05.2014, 13:20 15
Жадина из этого сделает
C++
1
((a++)++)+b
. Не вычисляется из-за того, что инкремент не инкермируется? А можно было бы вычислить, если разбить иначе, например,
C++
1
(a++)+(++b)
. Но так c++ не копмилит.
0
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)

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.05.2014, 13:25

как вычисляется следующее выражение
не знаю как использовать редактор формул поэтому сначала как звучит задание Для натуральных...

Как вычисляется это выражение?
Я только начала изучать js и у меня появился вопрос. var a = 1, b = 1, c, d; c = ++a;...

Неверно вычисляется выражение
Помогите пожалуйста с примером! Console.WriteLine("Здравствуйте!"); double x, y, z,...

Неправильно вычисляется выражение
Выводит 0,834370587875676 в результате, но должно выводить 0,7121 Работаю в Borland Builder C++ 6...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru