2013-06-10 2 views
-1
int main() 
{ 
    int value = 4321; 
    int *ptrVal = &value; 
    printf("%d %d",++value,(*(int*)ptrVal)--); 
    return 0; 
} 

Как работает предварительный приращение/пост-приращение в вышеприведенном заявлении на печать?pre-increment and post-increment in printf

И почему ответ 4321 4321?

ответ

3

Вы изменяете объект value дважды между двумя точками последовательности: вы вызываете неопределенное поведение. Неопределенное поведение означает, что ваша программа может печатать 4321 4321, печатать 42 или даже просто сбой.

Правильная версия вашей программы будет:

int value = 4321; 
int *ptrVal = &value; 

++value; 
(*ptrVal)--; // no need to cast to int * 

printf("%d %d", value, *ptrVal); // same as printf("%d %d", value, value); 

Конечно вам не нужна какой-либо временный указатель для достижения этой цели.

+1

Поскольку программа опроса была явно специально разработана для этой немного отличающейся версии «что происходит, когда я' printf («% d% d \ n», ++ i, i -) '», я не согласен с вашим что ваш пример является версией исправления программы: это просто версия программы, которая не вызывает Undefined Behavior. Независимо от конкретной реализации, основная цель программы опроса заключается в демонстрации Неопределенного поведения для целей запроса. Не может быть «правильной» версии Undefined Behavior. –

+0

@ ElchononEdelson * Я не согласен с вашим утверждением, что ваш пример является версией исправления программы: это просто версия программы, которая не вызывает Undefined Behavior. * Это был именно смысл моего утверждения. Правильная версия программы: версия программы, которая не вызывает неопределенное поведение. Программа, вызывающая неопределенное поведение, является * ошибочной * программой. – ouah

+0

Я не согласен. Я не вижу, как вы можете назвать программу «правильной», если она не соответствует цели дизайна. В этом случае цель дизайна, по-видимому, «нарушает правила языка для обсуждения», поэтому я продолжаю утверждать, что не может быть правильной версии этой программы. Кроме того, используя альтернативную интерпретацию «того, как выглядит программист, если это было найдено в реальном коде», использование оператора пост-декремента предполагает, что при исправлении кода мы должны декрементировать '(* prtVal)' _after_ вызов 'printf()'. –

1

Приведенный выше код просто сломан. Неизвестно, как это будет работать или каким будет ответ. Вам нужна точка последовательности между модификациями или изменениями и обращениями.

Смежные вопросы