El page d'accueil dit à propos de memset
:
#include <string.h> void *memset(void *s, int c, size_t n)
El
memset()
remplit le premiern
octets de la zone de mémoire pointée pars
avec l'octet constantc
.
Il est évident que memset
ne peut pas être utilisé pour initialiser int
comme indiqué ci-dessous :
int a[10];
memset(a, 1, sizeof(a));
c'est parce que int
est représenté par 4 octets (disons) et on ne peut pas obtenir la valeur désirée pour les entiers dans le tableau a
.
Mais je vois souvent les programmeurs utiliser memset
pour définir le int
à l'un ou l'autre des éléments du tableau 0
o -1
.
int a[10];
int b[10];
memset(a, 0, sizeof(a));
memset(b, -1, sizeof(b));
D'après ce que j'ai compris, l'initialisation avec des entiers 0
est OK parce que 0
peut être représenté par un octet (je me trompe peut-être dans ce contexte). Mais comment est-il possible d'initialiser b
con -1
(une valeur de 4 octets) ?
25 votes
Downvoter, vous pouvez expliquer ? Cette question n'est-elle pas pertinente pour ce site ou pour autre chose ?
0 votes
Vous avez légèrement tort quant à la raison pour laquelle l'initialisation avec
0
est OK. C'est OK parce que0
s'insère dans ununsigned char
(afin qu'il ne soit pas tronqué lorsqu'il est utilisé comme deuxième argument de la fonctionmemset
) y car la configuration binaire en mémoire pour unsizeof(int)
-L'octet zéro est identique à la configuration binaire en mémoire pour l'octet zéro.sizeof(int)
des zéros séquentiels d'un octet. Ces deux choses doivent être vraies pour que cela fonctionne. En fait, ces choses sont vraies pour exactement deux nombres en arithmétique à deux compléments :0
y-1
.0 votes
@zwol : Hmm ? La première phrase parle de zéros et n'est donc pas littéralement vraie pour 1. Donc on peut supposer que vous avez l'intention de paramétrer implicitement la première phrase : Cela fonctionne pour x si les bits d'un
int
avec valeur x sont les mêmes que les bits poursizeof(int)
unsigned char
chacun ayant la valeur x . De plus, nous devons considérer leunsigned char
avec valeur x comme résultant de la conversion de x aunsigned char
car 1 n'est pas représentable. Si c'est le cas, alors il n'est pas vrai que 0 et 1 sont les seules valeurs de ce type. 16,843,009 - x fonctionne pour tout nombre entier 0 x < 256. (16,843,009 est hex 1010101).0 votes
@zwol : A l'exception du fait que le C n'exige pas que les positions des bits dans des entiers de largeur différente représentent les mêmes valeurs.
0 votes
@EricPostpischil Je ne comprends pas votre exemple. Aucun multiple de 16,843,009 n'est représentable par l'une quelconque des
char
(enfin, à moins que vous ne soyez sur une machine où lesCHAR_BIT >= 25
.)0 votes
@zwol :
0x34343434
est un multiple de 16.843.009 ; il s'agit de0x34 * 0x01010101
.int a; memset(&a, 0x34343434, sizeof a);
mettra chaque octet dea
a0x34
. Alors la valeur dea
sera0x34343434
.0 votes
@EricPostpischil Oh, vous comptez sur la troncature interne du deuxième argument de
memset
. Je considère que c'est de la triche parce quememset
prendrait ununsigned char
deuxième argument si ce n'est pas pour le back-compat avec le C traditionnel.0 votes
@zwol : Mais vous l'avez fait avec le 1.
memset
prend unint
et le convertit en ununsigned char
et le copie dans chaque octet. 1 n'est pas représentable comme ununsigned char
; il est converti enUCHAR_MAX
. Donc, si vous autorisez cela, alors0x34343434
(ou une valeur similaire dans le cas d'implémentations C à plus gros octets) fonctionne de la même manière.0 votes
@EricPostpischil Conversion
(int)-1
asigned char
ne change pas sa valeur ; la conversion de 0x34343434 en une forme quelconque dechar
change sa valeur (lorsqueCHAR_BIT
a sa valeur habituelle). Je ne vois pas trop pourquoi vous vous acharnez sur l'opposition non signé/signé ; la question portait clairement sur les quantités signées.1 votes
@zwol :
memset
est défini en termes deunsigned char
. Il n'y a pas designed char
ochar
soit dans la question affichée, soit dans la spécification C dememset
.