У меня была небольшая игра с C++ сегодня и наткнулась на это, что я считал странным, но, возможно, более вероятно из-за недопонимания мной и отсутствия чистого C-кодирования в последнее время.C++. reinterpret_cast от double до unsigned char *
То, что я искал, первоначально было преобразование двойного в массив неподписанных символов. Я понял, что 64 бита double (sizeof (double) равно 8) теперь будут представлены в виде 8 8-битных символов. Для этого я использовал reinterpret_cast.
Итак, вот код для преобразования из double в char array, или, по крайней мере, я думал, что это то, что он делал. Проблема в том, что он возвращал 15 из strlen вместо 8, почему я не уверен.
double d = 0.3;
unsigned char *c = reinterpret_cast<unsigned char*> (&d);
std::cout << strlen((char*)c) << std::endl;
Таким образом, strlen был моей первой проблемой. Но затем я попробовал следующее и обнаружил, что он вернул 11, 19, 27, 35. Разница между этими числами равна 8, поэтому на каком-то уровне происходит что-то правильное. Но почему это не возвращается 15, 15, 15, 15, (поскольку он возвращал 15 в вышеприведенном коде).
double d = 0.3;
double d1 = 0.3;
double d2 = 0.3;
double d3 = 0.3;
unsigned char *c_d = reinterpret_cast<unsigned char*> (&d);
unsigned char *c_d1 = reinterpret_cast<unsigned char*> (&d1);
unsigned char *c_d2 = reinterpret_cast<unsigned char*> (&d2);
unsigned char *c_d3 = reinterpret_cast<unsigned char*> (&d3);
std::cout << strlen((char*)c_d) << std::endl;
std::cout << strlen((char*)c_d1) << std::endl;
std::cout << strlen((char*)c_d2) << std::endl;
std::cout << strlen((char*)c_d3) << std::endl;
Итак, я посмотрел на адреса символов, и они есть.
0x28fec4
0x28fec0
0x28febc
0x28feb8
Теперь это имеет смысл, учитывая, что размер беззнаковое символ * в моей системе составляет 4 байта, но я думал, что правильное количество памяти будет выделено из актеров, в противном случае, похоже reinterpret_cast является довольно опасная вещь ... Кроме того, если я сделаю
for (int i = 0; i < 4; ++i) {
double d = 0.3;
unsigned char *c = reinterpret_cast<unsigned char*> (&d);
std::cout << strlen((char*)c) << std::endl;
}
Отпечатано 11, 11, 11, 11!
Итак, что происходит здесь, ясно, что память переписывается в местах, а реинтерпрет приведения не работает, поскольку я думал, что это будет (то есть я использую это неправильно). Если вы так долго используете строки на C++, иногда, когда вы возвращаетесь к массивам необработанных символов, вы забываете об этом.
Итак, я полагаю, что это вопрос из трех частей.
Почему перл изначально возвращал 15? Почему четыре звонка увеличились? Почему цикл вернулся 11, 11, 11, 11?
Спасибо.
_casting_ не выделяет места для хранения. Использование 'reinterpret_cast' в основном говорит компилятору:« Эй, я знаю, что я делаю. Поверь мне ». Поэтому вам нужно знать, сколько мест хранения эти тезки могут указывать корректно. – Chad
@ У меня такие ответы на мой вопрос лучше. Как я уже сказал в комментарии к выбранному ответу, я ожидал слишком многого от кастинга. Я знаю символ \ 0, хотя это было действительно поведение reinterpret_cast, и что именно он сделал, что меня немного смутило. –