Приоритет операторов и ассоциативность с унарным оператором java [duplicate]

Поскольку OP упоминает о raw_input, это означает, что он хочет решение cli. Linux: curses - это то, что вы хотите (windows PDCurses). Curses, является графическим API-интерфейсом для программного обеспечения cli, вы можете добиться большего, чем просто обнаружить ключевые события.

Этот код будет обнаруживать клавиши до тех пор, пока не будет нажата новая строка.

import curses

def main(win):
    win.nodelay(True)
    key=""
    win.clear()                
    win.addstr("Detected key:")
    while 1:          
        try:                 
           key = win.getkey()         
           win.clear()                
           win.addstr("Detected key:")
           win.addstr(str(key)) 
           if key == os.linesep:
              break           
        except Exception as e:
           # No input   
           pass         

curses.wrapper(main)

40
задан frunkad 17 December 2015 в 19:55
поделиться

5 ответов

Выражения оцениваются слева направо. Скобки (и приоритет) просто выражают группировку, они не выражают порядок оценки.

Итак,

 11 * (12 + 5)
++a   ++a

равно

187
95
ответ дан Sotirios Delimanolis 25 August 2018 в 23:57
поделиться
  int a = 10;
  a = ++a * ( ++a + 5);

выше вида выражений всегда оцениваются слева направо так: C или JAVA

в этом случае он решает аналогично 11 * (12 + 5), что приводит к 11 * 17 = 187 // wrt java

, но если он решает одно и то же выражение по C-language

, тогда ответ изменяется как способ оценки изменений

в c происходит первый предварительный приращение / предварительный декремент, поэтому, если в выражении есть «N», то в выражении нет inc inc / dec, тогда inc / dec произойдет сначала «N» no times

то одно и то же значение будет заменено в каждом вхождении переменной в выражение и вычисляется значение выражения и после этого происходит приращение / декремент post

, т.е. a увеличивается с шагом 11, затем снова 12, так как есть два приращение для a в выражении, а затем выражение оценивается как

12 * (12 + 5) = 12 * 17 = 204 // wrt C-language

-1
ответ дан Debpratim Ghosh 25 August 2018 в 23:57
поделиться

Цитата из Блог Эрика Липперта :

Оценка арифметического выражения контролируется тремя наборами правил: правилами приоритета, правилами ассоциативности и правилами порядка.

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

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

Порядок правил оценки описывает порядок, в котором оценивается каждый операнд в выражении.

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


Обновление:

Как я вижу, многие программисты считают, что оператор

a = ++a * ( ++a + 5);  

будет вызывать неопределенное поведение. Да, он будет вызывать UB, если нет гарантии порядка оценки операндов оператора.

Но это не так в контексте языка Java-программирования. Он имеет четко определенное поведение в java (а также в C #). Спецификация языка Java гласит, что:

15.7. Порядок оценки

Язык программирования Java гарантирует, что операнды операторов, по-видимому, оцениваются в определенном порядке оценки, а именно слева направо.

Пример 15.7.1-1. Левый операнд оценивается сначала

В следующей программе оператор * имеет левый операнд, который содержит назначение переменной и правый операнд, содержащий ссылку к той же переменной. Значение, созданное ссылкой, будет отражать тот факт, что назначение произошло первым.

class Test1 {
    public static void main(String[] args) {
        int i = 2;
        int j = (i=3) * i;
        System.out.println(j);
    }
}

Эта программа производит вывод:

9

Не разрешено для оценка оператора * для получения 6 вместо 9 .

Но, по-прежнему спецификация java четко заявляет, что не писать такие коды:

Рекомендуется, чтобы код не опирался на эту спецификацию. Код обычно более ясен, когда каждое выражение содержит не более одного побочного эффекта, как его внешнюю операцию, и когда код не зависит от того, какое именно исключение возникает из-за оценки выражений слева направо.

28
ответ дан haccks 25 August 2018 в 23:57
поделиться

Из этого фрагмента

int a = 10;
a = ++a * ( ++a + 5);

Иногда наиболее простым решением является использование javap для понимания порядка оценки:

 0: bipush 10 // push 10 onto the stack (stack={10})
 2: istore_1  // store 10 into variable 1 (a = 10, stack={})
 3: iinc 1, 1 // increment local variable 1 by 1 (a = 11, stack={})
 6: iload_1   // push integer in local variable 1 onto the stack (a = 11, stack = {11})
 7: iinc 1, 1 // increment local variable 1 by 1 (a = 12, stack={11})
 10: iload_1  // push integer in local variable 1 onto the stack (a = 12, stack = {12, 11})
 11: iconst_5 // load the int value 5 onto the stack (a = 12, stack = {5, 12, 11})
 12: iadd     // add 5 and 12 (a = 12, stack = {17, 11})
 13: imul     // multiply 17 and 11 (a = 12, stack = {})
  1. a увеличивается на 1. (строка 3) // a = 11
  2. a увеличивается на 1. (строка 7) // a = 12
  3. добавляет 5 в a (строка 12) // a = 17
  4. умножить 11 на 17 (строка 13) // a = 187

(10 + 1 + 1 + 5) * 11 = 187

10
ответ дан Pier-Alexandre Bouchard 25 August 2018 в 23:57
поделиться

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

(a()+b()) * (c()+d())
a() + (b()*c()) + d()

Скобки не должны (и в Java не могут) влиять на порядок, в котором вызываются вызовы a (), b (), c () и d (). Они могут повлиять на то, выполняется ли умножение до или после вызова d (), но только в очень редких случаях (например, d () вызывает интерфейс Java Native, который изменяет режим численного округления, используемый в умножении, способом, которым Java не знает about) будет иметь какой-либо способ узнать или заботиться о том, выполнялось ли умножение до или после d ().

В противном случае важно то, что в первом случае одна операция добавления будет действовать на () и b (), а другой - на c () и d (); умножение будет действовать на () + b () и c () + d (). В другом случае первое умножение будет действовать на b () и c (), первое сложение на a () и вышеупомянутое произведение, а второе сложение на первую сумму и d ().

2
ответ дан supercat 25 August 2018 в 23:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: