В чем дело с изменением указателей? - PullRequest
0 голосов
/ 23 февраля 2019

У меня просто быстрый вопрос о постороннем числе ( 1684096032 ), выводимом на экран.Я ожидал, что будет выведено целочисленное значение ASCII (97), так как это значение ASCII в нижнем регистре 'a'.Консоль дала мне чудовищное число вместо ...

using namespace std;

int main(){
    char dadum[50] = "Papa Dadi";
    char* wicked = dadum;
    int* baboom = (int*)wicked;
    cout << baboom[1] << endl;
    cout<<"Hello World";

    return 0;
}

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Слово предупреждения

Приведение указателя на int*, который не был получен из int*, является неопределенным поведением, и компилятору разрешено делать буквально все что угодно.Это не просто теоретически: на некоторых рабочих станциях, на которых я кодировал, int* должен быть выровнен по четырехбайтовой границе, тогда как char* может и не быть, попытка загрузить смещенное 32-битное значение может привести ксбой процессора, и, следовательно, подобный код может или не может произойти сбой во время выполнения с «ошибкой шины».

Где происходит 1684096032

Компилятор здесь делает «здравый смысл»для настольного компьютера в 2019 году. Это позволяет вам «выстрелить себе в ногу», если можно так выразиться, выполняя инструкцию по загрузке с адреса, который вы указали по int*, без вопросов.То, что вы получаете, это мусор, который дает вам инструкция процессора.

То, что происходит, заключается в том, что "Papa Dadi" хранится в памяти как массив байтов, включая завершающий нулевой байт.Это эквивалентно, {'P','a','p','a',' ','D','a','d', 'i', '\0'}.("Papa Dadi" - это просто синтаксический сахар. Вы можете написать его в любом случае). Они хранятся в виде их значений ASCII 1 { 0x50, 0x61, 0x70, 0x61, 0x20, 0x44, 0x61, 0x64, 0x69, 0x00 }.

Вы собираетесь на машине с четырьмя-байт int, поэтому при добавлении псевдонима wicked к int* baboom, baboom[0] байтов псевдонимов 0–3 из wicked и baboom[1] байтов 4–7.Таким образом, в проверенной вами реализации вы случайно вернули байты "Dad", или в Hex, 20 44 61 64.

Затем вы собрали компиляцию для машины с прямым порядком байтов, так чтозагружается из памяти в «порядке обратных слов» 0x64614420.

Десятичное значение 1684096032.

Что вы хотите сделать

На основеВаши замечания: 2

cout << (int)wicked[1];

1 Очевидно, вы не используете единственное исключение - компилятор мэйнфреймов IBM.Они по-прежнему используют EBCDIC по умолчанию.

2 Консенсус здесь равен никогда для записи using namespace std;.Лично я научился использовать <iostream.h> и стандартную библиотеку C задолго до namespace std, и я все еще предпочитаю опускать std для них, чтобы вы могли сказать мой код с помощью блока команд, таких как using std::cout;.

0 голосов
/ 23 февраля 2019

Вы пытаетесь распечатать второе значение целочисленного массива, который указывает на строку «Папа Дади»

Вы должны знать, что целое число составляет 4 байта, а char - 1 байт.поэтому каждый элемент в массиве целых чисел пропускает 4-байтовые (символы) отпечаток, который вы видите "0x64614420" в шестнадцатеричном формате, что, когда вы подумаете о старшем порядке, вы увидите следующее

0x20 это пробел

0x44 - это 'D'

0x61 - это 'a'

0x64 - это 'd'

, поэтому вам нужно преобразовать big-endian вlittle-endian, если вы заботитесь о порядке.однако я не уверен, чего вы пытаетесь достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...