Как целочисленный литерал отображается в памяти?

#c

#c

Вопрос:

Взгляните на следующий пример:

 int a = 130;
char *ptr;
ptr = (char *) amp;a;
printf("%d", *ptr);
 

Я ожидал получить значение 0 , напечатанное на экране, но, к моему удивлению, это -126 . Я пришел к выводу, что, поскольку char это 8 бит int , может быть округление.

До сих пор я думал, что память заполняется таким образом, что msb находится слева. Но теперь все кажется смешанным. Как именно выделяется память?

Комментарии:

1. Большинство современных компьютеров имеют «малый порядковый номер» , при этом MSB условно находится справа .

2. @SteveSummit Значит, это противоположно тому, как мы пишем на бумаге?

3. @BhaiJaan Уверен, что это так. Поначалу это определенно сбивает с толку, но в конечном итоге дает некоторые реальные преимущества.

4. @SteveSummit Спасибо, Стив, я проверю преимущества.

5. Попробуйте это: int i = 16909060; unsigned char *p = amp;i; printf("x x x xn", p[0], p[1], p[2], p[3]);

Ответ №1:

в вашем случае a (может быть) 4 байта — маленькое конечное значение. а 130 — это 10000010 в двоичном формате.

 int a = 130; // 10000010 00000000 00000000 00000000 see little endianness here
 

и вы указываете на первый байт с помощью char*

 char* ptr = (char*)amp;a; // 10000010
 

и пытается распечатать его в %d формате, в котором будет напечатано целое число со знаком, значение 10000010 которого равно -126 (см.: Дополнение к двум)

Комментарии:

1. Как будто все знают об этом, кроме меня: D

2. @сумматор слева направо адрес увеличивается, а LSB сохраняется по самому низкому адресу

Ответ №2:

Ваш вывод — это намек на то, что ваша система имеет небольшой конечный код (младший значащий байт имеет наименьший адрес памяти).

В шестнадцатеричном формате (ровно 2 цифры на байт) 130 записывает 0x82. Предполагая, что 4 байта для int, в маленькой десятичной системе целое число будет сохранено как 0x82, 0, 0, 0. Так *ptr и будет (char) 0x82 .

Но вы используете printf для отображения его значения. Поскольку все параметры, переданные первыми, не имеют требуемого типа, значение char будет повышено до int. Здесь, предполагая представление с 2 дополнениями (наиболее распространенное в настоящее время), вы получите либо 130, если char оно не было подписано, либо -126, если оно подписано.

TL / DR: выходные данные являются нормальными в системе с небольшим конечным порядком с целочисленным представлением с 2 дополнениями и где char тип имеет знак.