Как memset инициализирует массив целых чисел на -1?
manpage говорит о memset
:
#include <string.h>
void *memset(void *s, int c, size_t n)
Функция memset()
заполняет первую n
байты области памяти, на которую указывает s
, с константным байтом c
.
Очевидно, что memset
не может использоваться для инициализации массива int
, как показано ниже:
int a[10];
memset(a, 1, sizeof(a));
это потому, что int
представляется 4 байтами (скажем), и невозможно получить желаемое значение для целых чисел в массиве a
.
Но я часто вижу, что программисты используют memset
для установки элементов массива int
либо 0
, либо -1
.
int a[10];
int b[10];
memset(a, 0, sizeof(a));
memset(b, -1, sizeof(b));
В соответствии с моим пониманием инициализация с помощью integer 0
является ОК, потому что 0
может быть представлена в 1 байт (может быть, я ошибаюсь в этом контексте). Но как можно инициализировать b
с помощью -1
(значение 4 байта)?
Ответы
Ответ 1
Как ни странно, причина, по которой это работает с -1
, точно такая же, как причина, что это работает с нулями: в двухкомпонентное двоичное представление, -1
имеет 1
во всех своих битах, независимо от размера целого числа, поэтому заполнение области байтами, заполненными всеми 1
, создает область -1
, подписанную int
s, long
s и short
на двух дополнительных аппаратных средствах.
На аппаратном обеспечении, отличном от двух дополнений, результат будет другим. Целочисленная константа -1
была бы преобразована в unsigned char
для всех, поскольку стандарт специфичен для того, как должно выполняться преобразование. Однако область байтов со всеми их битами, установленными в 1
, будет интерпретироваться как интегральные значения в соответствии с правилами платформы. Например, на аппарате с знаками и значениями все элементы вашего массива будут содержать наименьшее отрицательное значение соответствующего типа.
Ответ 2
Когда все биты числа равны 0
, его значение также равно 0. Однако, если все биты равны 1
значение равно -1.
Когда мы записываем int a[2]
, выделяется 4x2 байта памяти, которая содержит случайный мусор bits-
00110000 00100101 11100011 11110010 11110101 10001001 00111000 00010001
Затем мы пишем memset(a, 0, sizeof(a))
. Теперь memset()
не различает int
и char
. Работает побайтово. И одно байтовое представление 0 равно 00000000
. Итак, мы get-
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Следовательно, a[0]
и a[1]
инициализируются с 0.
Теперь давайте посмотрим memset(a, -1, sizeof(a))
: один байт для -1 равен 11111111
. И мы get-
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
Здесь и a[0]
и a[1]
будут иметь значение -1.
Однако для memset(a, 1, sizeof(a))
: 1 в байте равно 00000001
-
00000001 00000001 00000001 00000001 00000001 00000001 00000001 00000001
Итак, значение будет be- 16843009.