В вашем коде есть некоторые проблемы:
кажется, что существует некоторая путаница между бит и байт .Компьютерная память адресуется в байтах, обычно в современных архитектурах она содержит 8 бит.
Вы не должны приводить указатель к int
, int
может не иметь достаточного диапазона для размещения указателя.значение.преобразуйте указатели в unsigned char *
для исправления отдельных байтов, но имейте в виду, что это может не дать ожидаемых результатов из-за правила наложения имен:
((unsigned char *)x)[0] = 255; //adding to x's memory address
((unsigned char *)y)[1] = 255; //adding 1 byte over from y
((unsigned char *)z)[2] = 255; //adding 2 bytes over from z
((unsigned char *)a)[3] = 255; //adding 3 bytes over from a
Аналогично, вы должны использовать %zu
для печати size_t
или преобразования size_t
в int
.
- указатели должны быть отлиты как
(void*)
и напечатаны с %p
. - эффект ваших изменений будет более очевидным, если вы напечатаете значения
int
в шестнадцатеричном формате.
Вот модифицированная версия:
#include <stdio.h>
#include <stdlib.h>
int main() {
// getting 4 memory addresses, each with enough space for 2 int, initialized to 0
int *x = calloc(2, sizeof(int));
int *y = calloc(2, sizeof(int));
int *z = calloc(2, sizeof(int));
int *a = calloc(2, sizeof(int));
((unsigned char *)x)[0] = 255; //adding to x's memory address
((unsigned char *)y)[1] = 255; //adding 1 byte over from y
((unsigned char *)z)[2] = 255; //adding 2 bytes over from z
((unsigned char *)a)[3] = 255; //adding 3 bytes over from a
printf("%d\n", (int)sizeof(int));
printf("%08x,%08x -- %d,%d\n", x[0], x[1], x[0], x[1]);
printf("%08x,%08x -- %d,%d\n", y[0], y[1], y[0], y[1]);
printf("%08x,%08x -- %d,%d\n", z[0], z[1], z[0], z[1]);
printf("%08x,%08x -- %d,%d\n", a[0], a[1], a[0], a[1]);
printf("%p\n", (void *)x);
printf("%p\n", (void *)&x[1]);
return 0;
}
Вывод:
4
000000ff,00000000 -- 255,0
0000ff00,00000000 -- 65280,0
00ff0000,00000000 -- 16711680,0
ff000000,00000000 -- -16777216,0
0x7fd42ec02630
0x7fd42ec02634
Из приведенного выше вывода видно, что:
- тип
int
имеет 4 байта - указатели используют 8 байтов (мое окружение 64-битное, в отличие от вашего)
int
хранятся сначала с младшим значащим байтом, таким же, как ваш, который называется архитектура с прямым порядком байтов .
Вы ожидали обратного, архитектура с прямым порядком байтов , что довольно редко встречается на современных настольных и переносных компьютерах, но очень распространено на embedАрхитектура ded и мобильные телефоны.
Оба подхода имеют свои преимущества и недостатки.C поддерживает оба прозрачно, поэтому большинство программистов не знают об этих тонкостях, но понимание этих деталей реализации очень полезно в некоторых ситуациях:
- системное программирование, низкоуровневое программирование, разработка драйверов устройств,
- обработка изображений
- чтение и запись двоичных файлов и потоков,
- обработка сетевой передачи двоичных данных, особенно на и с различных устройств.
- взаимодействие с другими языками программирования, написание библиотек и т. д.