web-dev-qa-db-fra.com

Comment memset initialise un tableau d'entiers par -1?

Le manpage indique environ memset

#include <string.h>
void *memset(void *s, int c, size_t n)

La fonction memset() remplit la première noctets de la zone mémoire désignée par s avec l'octet constant c

Il est évident que memset ne peut pas être utilisé pour initialiser le tableau int comme indiqué ci-dessous: 

int a[10];
memset(a, 1, sizeof(a));  

c'est parce que int est représenté par 4 octets (par exemple) et on ne peut pas obtenir la valeur souhaitée pour les entiers du tableau a.
Mais je vois souvent que les programmeurs utilisent memset pour définir les éléments du tableau int sur 0 ou -1

int a[10];
int b[10];
memset(a, 0, sizeof(a));  
memset(b, -1, sizeof(b));  

Selon ma compréhension, l'initialisation avec l'entier 0 est correcte car 0 peut être représenté dans un octet (peut-être que je me trompe dans ce contexte). Mais comment est-il possible d’initialiser b avec -1 (une valeur de 4 octets)? 

60
haccks

Bizarrement, la raison pour laquelle cela fonctionne avec -1 est identique à la raison pour laquelle cela fonctionne avec des zéros: dans la représentation binaire du complément à deux , -1 a 1s dans tous ses bits, quelle que soit la taille de l'entier, afin de remplir une région avec des octets remplis de tous les 1s produit une région de -1 signé ints, longs et shorts sur du matériel à complément à deux.

Sur le matériel différent du complément à deux, le résultat sera différent. La constante entière -1 serait convertie en un unsigned char de tous, car la norme spécifie la manière dont la conversion doit être effectuée. Cependant, une région d'octets dont tous les bits sont définis sur 1 serait interprétée comme une valeur intégrale conformément aux règles de la plate-forme. Par exemple, sur le matériel de signe et magnitude, tous les éléments de votre tableau contiendraient la plus petite valeur négative du type correspondant.

68
dasblinkenlight

Lorsque tous les bits d'un nombre sont0, sa valeur est également 0 . Cependant, si tous les bits sont1la valeur est -1 .


Lorsque nous écrivons int a[2],4x2octets de mémoire sont alloués et contiennent des bits aléatoires/garbage-

00110000 00100101 11100011 11110010    11110101 10001001 00111000 00010001


Ensuite, nous écrivons memset(a, 0, sizeof(a)). Maintenant, memset() ne fait pas la distinction entre int et char. Cela fonctionne octet par octet. Et une représentation sur un octet de 0 est 00000000. Donc, nous obtenons

00000000 00000000 00000000 00000000    00000000 00000000 00000000 00000000

Par conséquent, a[0] et a[1] sont tous deux initialisés avec 0 .


Voyons maintenant memset(a, -1, sizeof(a)): Un octet pour -1 est 11111111. Et nous

11111111 11111111 11111111 11111111    11111111 11111111 11111111 11111111

Ici, a[0] et a[1] auront la valeur -1 .


Cependant, pour memset(a, 1, sizeof(a)): 1 dans un octet est 00000001-

00000001 00000001 00000001 00000001    00000001 00000001 00000001 00000001

Ainsi, la valeur sera- 16843009 .

0
Minhas Kamal