Кастинг между целыми числами и указателями в C++

#include<iostream>
using namespace std;

int main()
{
  int *p,*c;
  p=(int*)10;
  c=(int*)20;
  cout<<(int)p<<(int)c;
}

Кто-то спросил меня "Что не так с вышеупомянутым кодом?" и я не мог понять это. Кто-то помогите мне.

7
задан jalf 3 January 2010 в 13:02
поделиться

7 ответов

Некоторым нужна была цитата из стандарта C++ (я бы поместил это в комментарии этого ответа, если бы формат комментариев не был так ограничен), вот два из 1999 года:

5.2.10/3

Определена реализация отображения, выполненного reinterpret_cast.

5.2.10/5

Значение интегрального типа или типа перечисления может быть явно преобразовано в указатель. Указатель преобразуется в целое число достаточного размера (если таковое существует на реализации Ant) и обратно к тому же типу указателя будет иметь свое исходное значение; связки между указателями и Целые числа в противном случае определяются реализацией.

И я не вижу ничего обязывающего в том, чтобы такое implementation-defined mapping давало действительное представление для всех входных данных. Иначе говоря, реализация на архитектуре с регистрами адресов может очень хорошо заманить в ловушку при выполнении

p = (int*)10;

, если отображение не дает действительного в это время представления (да, то, что является действительным представлением для указателя, может зависеть от времени. Например, delete может сделать недействительным представление удалённого указателя).

8
ответ дан 6 December 2019 в 11:49
поделиться

Предполагая, что я прав, это должно выглядеть следующим образом:

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).

1
ответ дан 6 December 2019 в 11:49
поделиться

адреса p и c могут быть больше, чем int.

0
ответ дан 6 December 2019 в 11:49
поделиться

Вы присваиваете указателям значения (10 и 20), что, очевидно, является потенциальной проблемой, если вы попытаетесь прочитать данные по этим адресам. Присвоение указателя целому числу также очень уродливо. И ваша главная функция не имеет оператора возврата. Это всего лишь несколько вещей.

0
ответ дан 6 December 2019 в 11:49
поделиться

более или менее все неправильно:

int *p,*c;
p=(int*)10;
c=(int*)20;
  • после этого p указывает на адрес памяти 10
  • после этого c указывает на адрес памяти 20

Это выглядит не очень умышленно.

И я полагаю, что вся программа просто рухнет.

-1
ответ дан 6 December 2019 в 11:49
поделиться

Тот факт, что INT и типы данных указателя не обязаны иметь одинаковое количество битов, согласно стандарту C ++, это одно - это означает, что вы можете потерять точность.

Кроме того, отливка INT к указателю INT , затем снова глупо. Почему бы не просто оставить его как int ?

Я на самом деле сделал . Постарайся скомпилировать это под GCC, и он работал нормально, но это, вероятно, больше случайно, чем хороший дизайн.

9
ответ дан 6 December 2019 в 11:49
поделиться

Проблема на некоторых платформах, которые вам нужны

p = (int*) (long) 10;

, см. Документацию Glib на макросах преобразования типа .

И для людей, которые могут не находить использование для этого типа выражений, можно вернуть данные в функции возврата значений указателя. Вы можете найти реальные примеры, где этот случай лучше использовать эту идиому вместо того, чтобы выделять новое целое число на куче, и вернуть его обратно - плохие характеристики, фрагментацию памяти, просто уродливо.

0
ответ дан 6 December 2019 в 11:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: