Выделение указателя/адреса
У меня есть следующие переменные:
char *p;
int l=65;
Почему выполняются следующие откаты?
(int *)p=&l;
и
p=&((char) l);
Ответы
Ответ 1
Результат преобразования типа всегда является rvalue. Rvalue не может быть назначено, поэтому ваше первое выражение не компилируется. Rvalue не может принимать адрес, поэтому ваше второе выражение не компилируется.
Чтобы выполнить правильное преобразование типов, вы должны сделать это следующим образом:
p = (char *) &l;
Это правильный способ сделать то, что вы пытались сделать в своем втором выражении. Он преобразует указатель int *
в тип char *
.
Ваше первое выражение не подлежит ремонту. Вы можете сделать
*(int **) &p = &l;
но то, что он делает в конце, на самом деле не является преобразованием, а скорее переинтерпретацией памяти, занятой указателем char *
в качестве указателя int *
. Это уродливый незаконный хак, который в большинстве случаев имеет мало практической ценности.
Ответ 2
Правильный способ сделать это:
int I = 65;
char* p = (char*)&I;
&I
дает int*
, который указывает на I
; вы затем передаете его в char*
и назначаете его p
.
Обратите внимание, что вы не должны указывать между указателями несвязанных типов. A char*
может использоваться для доступа к любому объекту, хотя в этом конкретном случае он безопасен.
Ответ 3
(int *) p = & l;
Строка выше не работает, потому что как только вы отбрасываете p на (int *), результатом является анонимный временный объект, который является rvalue, а не lvalue; последовательно результат не может получить задание, и даже если язык его допустил, вы должны назначить временную литую копию p, а не оригинальную p.
p = & ((char) l);
Строка выше не работает по той же причине; результат (char) l - временный объект, который является копией l, приложенной к типу char. Следовательно, поскольку он является временным, вы не можете принимать его адрес.
Insead, вы можете использовать:
p = (char*) &l
Ответ 4
В простой C, которая не является такой строгой, чтобы печатать конверсии, этот код будет компилироваться и фактически работать. На компиляторе С++ на самом деле требовались явные приведения, как уже упоминалось (см. Другие ответы).
Ответ 5
Проблема заключается в том, что когда вы выполняете броски (помимо того, что вы делаете это, хорошая идея или нет) заключается в том, что выражение для выражения выражает rvalue.
rvalues не могут быть назначены или приняты их addreses.