На этот вопрос нет ответа: ваш код демонстрирует неопределенное поведение. Он может напечатать «правильное значение», как вы видите, он может напечатать что-нибудь еще, может вызвать ошибку, он может заказать пиццу онлайн с помощью вашей кредитной карты.
Разыменование этого указателя в main
недопустимо, оно не указывает на действительную память в этой точке. Не делай этого.
Между двумя примерами есть большая разница: в первом случае *pointer
оценивается перед вызовом printf
. Таким образом, учитывая, что между строкой, в которой вы получаете значение указателя, и printf
нет вызовов функций, высока вероятность того, что расположение стека, на которое указывает pointer
, не будет перезаписано. Таким образом, значение, которое было сохранено там до вызова printf
, скорее всего, будет выведено (что значение будет передано в стек printf
, а не в указатель).
Во втором случае вы передаете указатель на стек printf
. Вызов printf
перезаписывает (часть) той же области стека, на которую указывает указатель, и printf
заканчивает тем, что пытается напечатать свой собственный стек (более или менее), который не имеет больших шансов что-то содержать читаемый.
Обратите внимание, что вы не можете полагаться на тарабарщину . Ваша реализация может использовать другой стек для вызова printf
, если он на это похож, если он соответствует требованиям, установленным стандартом.