Ваша программа вызывает неопределенное поведение, поэтому нет правильного или неправильного.В частности:
*p = 65;
записывает целое число в память, оставляя место только для char
.C99 §6.5.3.2 / 4 (Операции с адресом и косвенной адресацией):
Если операнд имеет тип '' указатель на тип '', результат имеет тип '' тип ''.Если указателю было присвоено недопустимое значение, поведение унарного оператора * не определено.84)
p
имеет указатель типа на int
, поэтому *p
имеет тип int
.Однако p
не является адресом действительного int
объекта.
Кроме того, я считаю, что приведение в левой части назначения является недопустимым (GCC определенно так считает).
Я полагаю, что происходит то, что это выложено (увеличение адреса) как:
|i|i|i|i|d|c|p|p|p|p|
Это представляет байты, которые каждый занимает.Я рассмотрю то, что, по-моему, происходит:
p = &i;
|i|i|i|i|d|c|00|00|00|00|
Для простоты я предполагаю, что адрес i
равен 0.
*p=10;
|10|0|0|0|d|c|00|00|00|00|
p=&c;
|10|0|0|0|d|c|05|00|00|00|
*p=65;
|i|i|i|i|d|65|00|00|00|00|
Обратите внимание, что изменение *p
перезаписываетp
.
p=&d;
|10|0|0|0|d|65|04|00|00|00|
*p=66;
|10|0|0|0|66|00|00|00|00|00|
Таким образом, сохранение до d
заменяет c
на NULL.Вышеприведенное применимо, если ваша машина имеет младший порядок байтов, имеет 4-байтовые числа и стек растет вверх (по направлению к младшим адресам).Анализ отличается, если у вас есть 2-байтовые числа, но основной вывод все еще применим.
Возвращение void
также недопустимо, но это не имеет отношения.