#include<iostream>
using namespace std;
int main()
{
int *p,*c;
p=(int*)10;
c=(int*)20;
cout<<(int)p<<(int)c;
}
Кто-то спросил меня "Что не так с вышеупомянутым кодом?" и я не мог понять это. Кто-то помогите мне.
Некоторым нужна была цитата из стандарта C++ (я бы поместил это в комментарии этого ответа, если бы формат комментариев не был так ограничен), вот два из 1999 года:
5.2.10/3
Определена реализация отображения, выполненного
reinterpret_cast
.
5.2.10/5
Значение интегрального типа или типа перечисления может быть явно преобразовано в указатель. Указатель преобразуется в целое число достаточного размера (если таковое существует на реализации Ant) и обратно к тому же типу указателя будет иметь свое исходное значение; связки между указателями и Целые числа в противном случае определяются реализацией.
И я не вижу ничего обязывающего в том, чтобы такое implementation-defined mapping давало действительное представление для всех входных данных. Иначе говоря, реализация на архитектуре с регистрами адресов может очень хорошо заманить в ловушку при выполнении
p = (int*)10;
, если отображение не дает действительного в это время представления (да, то, что является действительным представлением для указателя, может зависеть от времени. Например, delete
может сделать недействительным представление удалённого указателя).
Предполагая, что я прав, это должно выглядеть следующим образом:
int main()
{
int *p, *c;
// Something that creates whatever p and c point to goes here, a trivial example would be.
int pValue, cValue;
p = &pValue;
c = &cValue;
// The & operator retrieves the memory address of pValue and cValue.
*p = 10;
*c = 20;
cout << *p << *c;
}
Чтобы присвоить или получить значение переменной, на которую ссылается указатель, необходимо убрать ссылку .
В вашем коде происходит приведение 10 к указателю на int (который является адресом памяти, по которому находится реальный int).
Вы присваиваете указателям значения (10 и 20), что, очевидно, является потенциальной проблемой, если вы попытаетесь прочитать данные по этим адресам. Присвоение указателя целому числу также очень уродливо. И ваша главная функция не имеет оператора возврата. Это всего лишь несколько вещей.
более или менее все неправильно:
int *p,*c;
p=(int*)10;
c=(int*)20;
Это выглядит не очень умышленно.
И я полагаю, что вся программа просто рухнет.
Тот факт, что INT
и типы данных указателя не обязаны иметь одинаковое количество битов, согласно стандарту C ++, это одно - это означает, что вы можете потерять точность.
Кроме того, отливка INT
к указателю INT
, затем снова глупо. Почему бы не просто оставить его как int
?
Я на самом деле сделал . Постарайся скомпилировать это под GCC, и он работал нормально, но это, вероятно, больше случайно, чем хороший дизайн.
Проблема на некоторых платформах, которые вам нужны
p = (int*) (long) 10;
, см. Документацию Glib на макросах преобразования типа .
И для людей, которые могут не находить использование для этого типа выражений, можно вернуть данные в функции возврата значений указателя. Вы можете найти реальные примеры, где этот случай лучше использовать эту идиому вместо того, чтобы выделять новое целое число на куче, и вернуть его обратно - плохие характеристики, фрагментацию памяти, просто уродливо.