long a = 2829155;
cout << reinterpret_cast< char* >(&a);
Выведется строка «c++». Не отдам руку на отсечение, что у всех она будет именно такой, это требует дополнительного исследования.В первой строке записали четырехбайтовое число. Затем взяли адрес переменной и нагло наврали компилятору, что этот адрес совсем не указатель на long. Это указатель на char. Как компилятор интерпретирует указатель на char? Как строку.
Почему именно «с++»? 2829155 == 0x002B2B63. То есть число 2829155 хранится в виде последовательности байт: 0x63(==99), 0x2B(==43), 0x2B(==43), 0x0(==0). Если посмотреть таблицу символов, то убедимся, что 99 это символ «c», а 43 – «+». Байт с нулем интерпретируется как конец строки.
Совсем нетрудно написать программу обратного преобразования, из строки в число
Я не смогу толково объяснить все тонкости reinterpret_cast, для этого есть учебники. Однако, точно могу сказать, что он запросто превращает указатель одного типа в указатель другого. А это влечет совершенно другую интерпретацию байтов памяти, в чем можно убедиться выше. Об опасностях нетрудно догадаться. Если в примере взять число побольше, то 4-й байт уже не будет равен нулю. Значит, приведенная к char* строка будет продолжаться до первого нуля, но уже неизвестно где он будет.
С классами тоже интересно.
class A {
public:
int i;
};
void main(){
int b = 1;
cout << (*reinterpret_cast< A* >(&b)).i; /*1*/
}
Тут говорится, что по адресу &b вовсе не число, а переменная класса A. Нужно ли говорить насколько это все опасно.
Первый пример немного неправильный, не хватает типа, к которому приводим.
ОтветитьУдалитьlong a = 2829155;
cout << reinterpret_cast(&a);
Да верно, спасибо! Парсер решил, что это тег :)
ОтветитьУдалитьОй, а у меня в комментарии тоже удалил его ))))
ОтветитьУдалить