Оценка экспрессии в С - PullRequest
2 голосов
/ 23 июля 2011

Почему следующий фрагмент кода C печатается 12 12 12

int main(int argc, char const *argv[]) {
  int a = 2, *f1, *f2;
  f1 = f2 = &a;
  *f2 += *f2 += a += 2.5;
  printf("%i %i %i\n", a, *f1, *f2);
  return 0;
}

Ответы [ 3 ]

11 голосов
/ 23 июля 2011
*f2 += *f2 += a += 2.5;

Эта строка имеет Неопределенное поведение , поскольку вы изменяете значение *f2 (т. Е. a) более одного раза в одном выражении без промежуточной точки последовательности. UB означает, что ваша программа может напечатать «Hello World», может произойти сбой, она может напечатать 12 12 12 или 12 12 1029, или она может начать пожирать ваши мозги. Не полагайтесь на неопределенное поведение.

Цитировать стандарт C ++ (я знаю, что вопрос помечен буквой C, но у меня нет стандарта C, и я знаю, что в C действует то же правило)

За исключением отмеченных случаев, порядок вычисления операндов отдельных операторов и подвыражений отдельных выражения и порядок, в котором происходят побочные эффекты, не определены.53) Между предыдущими и в следующей точке последовательности скалярный объект должен иметь сохраненное значение, измененное не более одного раза в результате оценки выражения. Кроме того, предварительное значение должно быть доступно только для определения значения, которое будет сохранено. Требования этого параграфа должны выполняться для каждого допустимого порядка подвыражений полного выражение; в противном случае поведение не определено .

1 голос
/ 23 июля 2011

I, потому что *f2 и *f1 указывают на a (целое число).

Итак *f2 = &a = 2 и *f1 = &a = 2

В этот момент вы добавляете кзначение 2.5 (поскольку a является целым числом, вы получите 4).

Чем у вас есть

a = 4
f2 = 4
f1 = 4

На данный момент вы делаете f2+f1+a = 12.

1 голос
/ 23 июля 2011

Он выводит одинаковое значение для всех, потому что вы указываете только на одну int переменную: a.

Он печатает 12, потому что a + 2.5 = 4 (a - это int), а затем вы добавляете его себе дважды.


@ Downvoters: Почему так негативно? Я думаю, что мой ответ говорит о том, что этот компилятор делает с этим примером кода , что должно помочь ОП понять поведение. Я согласен, что Армен Цирунян ответ правильный (то есть должен получить галочку) и что поведение не определено в соответствии со стандартом . Но стандарты реализованы, и мне еще предстоит увидеть компилятор, который компилирует код, а затем во время выполнения неожиданно подбрасывает руки и говорит Undefined behaviour!.

...