Быстрый ответ
Они отличаются, потому что в вашем первом примере int *p=0;
вы объявляете p как указатель, а затем устанавливаете его так, чтобы он указывал на адрес 0x0.Этот пример из одной строки эквивалентен этим двум строкам кода int *p; p=0;
Во втором примере int *p; *p=0;
вы объявляете p в первой строке, но он не инициализируется ... поэтому p указывает куда-тоне определено.Во второй строке вы идете по адресу в этом неопределенном месте и пытаетесь установить значение по этому адресу равным 0.
Вы можете увидеть разницу между этим примером и эквивалентным 2-строчным примером ранее, потому чтоодин использует p=0;
, а другой - *p=0;
Пример
Поэтому, прежде чем пытаться получить доступ к * p, вы хотите определить, куда указывает p.Предположим, вы знаете, что адрес целого числа, на которое хотите указать p, равен 0x76543210.Давайте посмотрим на значения в памяти до запуска кода:
// Dummy Memory Dump
// Offset: 0 4 8 C
// (0x76543200): 00000000 00000000 00000000 00000000
// (0x76543210): 00000000 00000000 00000000 00000000
// (0x76543220): 00000000 00000000 00000000 00000000
Я изменил ваш *p=0;
на *p=5;
в этом примере, чтобы мы могли видеть изменения в памяти.Итак, давайте предположим, что мы запустили следующие строки кода:
int *p; // Declare a pointer p
p = (int*) 0x76543210; // Set p to point at the address 0x76543210 cast to (int*)
*p = 5; // Go to the address that p is pointing to, and set the value to 5
Теперь, если мы вернемся назад и посмотрим, что у нас в памяти, мы должны увидеть, что мы установили 5 на адрес, на который указывал p:
// Dummy Memory Dump
// Offset: 0 4 8 C
// (0x76543200): 00000000 00000000 00000000 00000000
// (0x76543210): 00000005 00000000 00000000 00000000
// (0x76543220): 00000000 00000000 00000000 00000000
Объяснение
Как правило, объявление разбивается на следующие компоненты:
[type] [name];
И, возможно, встроенная инициализация может быть нарушена следующим образом:
[type] [name] = [value];
В этом примере:
int *p=5;
- [type] = (int *)
- [name] = p
- [значение] = 5
Это может сбивать с толку, поскольку * в объявлении прикреплено к имени.Символ * в объявлении означает, что p является указателем.Но имя указателя по-прежнему просто p.
Итак, теперь, когда мы знаем компоненты, мы можем сказать, что
int *p=5;
эквивалентно
int *p;
p=5;
Теперь, чтобы добавить к путанице, есть разница между * при объявлении указателя и при обращении к адресу указателя.Когда вы используете * во время доступа, он использует значение в p как адрес, к которому будет осуществляться доступ.В этом примере:
int *p; // This declares a pointer p with no value
*p=5; // This line wants to go to the address that p is pointing to and set it to 5
// At this point, p is undefined because p was just declared and hasn't been set
// So it is trying to go to an unknown location to set the value 5.