EDIT: этот вопрос не повторяется, поскольку в этом случае поведение не является неопределенным.
Почему приведенная ниже программа выводит вывод как 231 в первой строке?
У меня есть два сомнения по этому поводу:
Поскольку я делаю постфиксное приращение, значение x не должно было увеличиваться до того, как я вызываю функцию max. Таким образом, на мой взгляд, вывод должен был быть 1 вместо 2. Что мне не хватает?
#define prn(a) printf("%d",a) #define print(a,b,c) prn(a), prn(b), prn(c) #define max(a,b) (a<b)? b:a main() { int x=1, y=1; print(max(x++,y),x,y); printf("\n"); print(max(x++,y),x,y); }
Выход:
231 451
Постфиксная операция происходит после выполнения оператора? Рассмотрим пример ниже.
int main() { int x = 0, y = 1; int a = x++ /*x is incremented hereafter?*/+ y; // line 1 /* Or x is incremented now after execution of above line?*/ // line 2 int b = 0; }
x++
. Итак, сначала компилятор заменилprint(max(x++,y),x,y);
и расширил доprn((x++<y) ? y:x++), prn(x), prn(y)
, а затем доprintf("%d",(x++<y)? y:x++), printf("%d",x), printf("%d",y);
. Затем выполняется строка get, первый printf печатает 2,x++<y ? y:x++
- первая проверка возвращает false, затем происходит первый x++, затем оператор возвращает 2 и снова увеличиваетx++
. Затем код печатает3
, так какx
было увеличено дважды. Второйprint(max...)
делает то же самое. - person KamilCuk   schedule 13.10.2018printf("%d",(x++<y)? y:x++), printf("%d",x), printf("%d",y)
, и это не UB,?
отмечает точку последовательности, как C11 6.5.15p4. - person KamilCuk   schedule 13.10.2018printf("%d",(x++<y)? y:x++)
проверит, еслиx++<y
ложно, потому что (x=1, y=1), он выполнитx++
, т.е.x=2
, потому что?
— это точка следования. Затем он оценит второе выражение после:
, т.е.x++
- таким образом вернуть 2 и увеличить x=3. Тогда это будетprintf("%d", 2)
. Второйprinf("%d", x)
напечатает3
. Может быть, вы видите ? оператор. - person KamilCuk   schedule 13.10.2018x
увеличивается на единицу после того, как компилятор видитx++
в самой строке 1, но использует значениеx = 0
для вычисленияa
и добавляет к немуy
, верно? - person Michelle   schedule 13.10.2018?:
имеет точку последовательности, поэтому первое приращениеx
должно быть выполнено доx++
после:
. - person M.M   schedule 13.10.2018