Они либо точно такие же по определению, либо почти одинаковые, в зависимости от версии версии стандарта C, с которой вы имеете дело.
В ISO C99 и C11, мы имеем следующую формулировку (со ссылкой на проект N1570 С11) в 6.5.3.2:
Унарный &
оператор дает адрес операнда. Если операнд имеет тип «тип», результат имеет тип «указатель на тип». Если операнд не является результатом унаров *
оператора, ни того оператор, ни оператор &
вычисляется и результат, как если бы оба были опущены, за исключением того, что ограничения на операторы до сих пор применяются и результат не является именующий.
Так Дано:
int *x = /* whatever */;
int *y;
эти два точно эквивалентны, даже если x
пустой указатель:
y = x;
y = &*x;
Без правила специального случая, поведение будет undefined, так как поведение оператора *
определяется только в том случае, если его операнд является допустимым непустым указателем. Но так как *
никогда не оценивается, он не имеет здесь никакого поведения, определенного или иного. (Тот факт, что, в отличие от x
, &*x
не именующий здесь не имеет значения.)
И в C89/C90, еще не было добавлены, что правила специального случая, так что поведение &*x
является не определенно, если x
- это указатель null (или иначе недействительный). Большинство компиляторов pre-C99, вероятно, оптимизируют *
и &
; помните, что характер неопределенного поведения что-то может вести себя так, как вы могли ожидать, что он будет себя вести.
С другой стороны, существует очень реальная разница в поведении любого, кто читает код. Если я вижу y = x;
, мое поведение должно думать «О, это обычное назначение указателя». Если я вижу y = &*x;
, мое поведение должно подумать: «Зачем ты это написал?» И изменить его на y = x;
, если я в состоянии это сделать.
AFAIK, да. * x - это lvalue, & * x - его адрес, который является x. не должно быть никаких побочных эффектов. – Elazar
(Реальный вопрос, конечно, что происходит, когда 'x == NULL') – Elazar
@ Элазар: Это не имеет значения. Это не сбой. – anishsane