Имеет ли выражение a=(a++)*(++b) для a=3 и b=2 правильный или наиболее приемлемый ответ? Если так, то что это?
Пожалуйста помоги! Я попал в беду. Этот вопрос был задан мне в колледже, и учитель почти ничего не объяснил. Для меня имело смысл, что ответом будет 10, учитывая, что исходное значение существа 3 умножается на увеличенное значение 3 b, а затем после выполнения выражения значение 9 присваивается a. Пост приращения затем увеличивает его значение до 10.
Учитель сказал, что я просто неправ. Никаких объяснений. Он просто сказал, что а здесь не будет увеличено.
Сейчас я проверил несколько сайтов, чтобы расследовать эту проблему. Я узнал, что такие случаи, как i=i++ или a=a++, не определены, и их следует избегать любой ценой. Но когда он был предоставлен в тесте в колледже, а затем оценки теряются, у меня не было возможности избежать этого и пройти мимо.
Просматривая Интернет, я наткнулся на этот сайт, который показывает разные значения для разных компиляторов: http://gynvael.coldwind.pl/?id=372
Теперь вот мой вопрос еще раз. Есть ли вообще какой-нибудь правильный ответ? Я понимаю, что большинство компиляторов в конечном итоге будут показывать 9 в результате процесса замены стека (который преподается Google, но не в колледже, в котором я учусь), и я также понимаю, что в некоторых случаях компилятор будет следовать моей логике, которая имеет больше смысла для меня, так как "++" здесь без всякой причины, если он не будет даже увеличивать переменную, не имеет смысла для меня, и я не вижу цели этого, и при этом Google не мог показать мне цель для этого пути логики. В любом случае, я должен утверждать, что мой ответ не заслуживает крестика (✘), или я должен просто принять его вместо нацеливания на галочку (✔) и не потерять ни одной оценки.
1 ответ
Здесь есть два разных ответа.
Правильный ответ, конечно же, "это неопределенный". Как только мы узнаем об этом, бессмысленно выяснять, может ли быть ответ 9, 4, 10, или "сорок два", или "бесцветные зеленые идеи", или дым, выходящий из экрана вашего компьютера. Слишком много слов уже написано о том, почему оно не определено, поэтому я не буду больше репетировать эти аргументы здесь.
Но время от времени вы сталкиваетесь с инструктором, который знает меньше, чем вы, а это означает, что если вы хотите получить лучшую оценку, ваша задача - выяснить, не какой ответ правильный, а какой ответ вашему инструктору. считает правильным.
Итак, учитывая, что этот второй вопрос практически не связан с языком программирования C, мы можем спросить, что бы мог подумать ваш инструктор a = a++ * ++b
может означать? Есть две вероятные интерпретации:
Интерпретация 1: a++
дает 3 и присваивает 4 a
, ++b
дает 3 и назначает 3 b
, 3 * 3 - это 9, которое назначено a
,
Интерпретация 2: Как и выше, но мы замечаем, что две разные вещи присваиваются a
и мы не знаем, в каком порядке они произойдут, так что, может быть, a
в конечном итоге содержит 4 в конце.
Опять же, я не говорю о Си здесь. В C мы просто не можем сказать, что означает это выражение, кроме того, что оно не определено. В C интересно, будет ли присвоение 4 или 9 a
"произойдет первым" почти наверняка доставит вам неприятности. Пять других завсегдатаев Stackru парят над кнопкой "Комментарий" прямо сейчас, ожидая, чтобы сказать мне, что я так же неправ, как ваш инструктор, даже за то, что даже предложил мои интерпретации 1 и 2 выше.
Но в заключение я должен сказать, что я бы посчитал 10 менее вероятным результатом. И хотя я не удивлюсь получению 10, если бы я действительно получил этот результат, это было бы просто потому, что для неопределенного выражения возможен любой результат, и результат может быть по существу случайным, основываясь на глупых причудах компилятора что никто (кроме, возможно, автора компилятора) никогда не поймет.
Но чтобы вернуться к вашему вопросу, вы предполагаете, что одна вещь, которую может сделать компилятор, это получить 9 для a
, а затем добавить 1 к нему из-за a++
часть, не так уж и вероятно. То, как я думаю о a++
, и я считаю, хороший способ думать о том, как думает компилятор a++
-это: "взять a
's value, добавьте единицу к нему, выведите старое (неинкрементное) значение в окружающее выражение, запишите, чтобы сохранить увеличенное значение обратно в a
некоторое время спустя (но до следующей точки последовательности)". Я не ожидал бы, что фактический компилятор сделает заметку для себя, чтобы получить a
значение позже и добавьте 1 к нему (в этом случае получая 10). Поэтому я не согласен с вашим инструктором в том, что вы не правы, но я согласен с тем, что компилятор вряд ли что-то сделает (хотя, полагаю, мог бы).