Dupliquer possible:
confusion dans scanf () avec l’opérateur &
Pourquoi nous avons besoin d’un & in scanf pour saisir un entier et pourquoi pas pour des caractères. Est-ce que le & in scanf fait référence au lieu de mémoire lors de la saisie?
Par exemple:-
main() { int a; char c; scanf("%d",&a); scanf("%c"c); }
Pour chaque spécificateur de conversion, scanf()
s’attend à ce que l’argument correspondant soit un pointeur sur le type approprié: %d
attend un argument de type int *
, %f
attend un argument de type double *
, %c
et %s
attendent tous deux un argument de type char *
, etc.
La différence entre %c
et %s
réside dans le fait que le premier indique à scanf()
de lire un seul caractère et de le stocker à l’emplacement spécifié par l’argument correspondant, tandis que le second indique à scanf()
de lire plusieurs caractères jusqu’à voir apparaître un caractère 0- valeur et enregistrez tous ces caractères dans la mémoire tampon en commençant à l’emplacement spécifié par l’argument.
Vous devez utiliser l’opérateur &
sur vos arguments s’ils ne sont pas déjà de type pointeur. Par exemple:
int x; int *px = some_valid_memory_location_such_as_&x; char c; char *pc = some_valid_memory_location_such_as_&c; ... scanf("%d", &x); // x is not a pointer type, so we must use the & operator scanf("%d", px); // px is a pointer type, so we don't need the & operator scanf("%c", &c); // etc. scanf("%c", pc); // etc.
La lecture de chaînes de caractères (à l’aide du spécificateur de conversion %s
) est source de confusion:
char buf[SIZE]; scanf("%s", buf); // expression 'buf' *implicitly* converted to pointer type
Pourquoi n’avons-nous pas besoin de l’opérateur &
dans ce cas? Cela a à voir avec la façon dont C traite les expressions de tableau. Lorsque le compilateur voit une expression de type tableau (tel que buf
dans l’appel scanf()
), il convertit implicitement l’expression du type N-element array of T
en pointer to T
, et définit sa valeur sur l’adresse du premier élément dans le tableau. Cette valeur n’est pas une valeur – elle ne peut pas être affectée (vous ne pouvez donc pas écrire quelque chose comme buf = foo
). Les seules exceptions à cette règle concernent le cas où l’expression de tableau est un opérande des opérateurs sizeof
ou &
, ou si l’expression de tableau est un littéral utilisé pour initialiser un autre tableau:
char *p = "This is a test"; // ssortingng literal implicitly converted to char *, // ssortingng *address* written to p char a[] = "This is a test"; // ssortingng literal not implicitly converted, // ssortingng *contents* copied to a
En bref, l’expression buf
est convertie implicitement de type char [SIZE]
à char *
. Il n’est donc pas nécessaire d’utiliser l’opérateur &
, et en fait, le type de l’expression &buf
serait pointer to SIZE-element array of char
, ou (*)[SIZE]
, ce qui n’est pas ce que scanf()
attend du spécificateur de conversion %s
.
Le symbole esperluette est requirejs dans les deux cas. scanf nécessite des pointeurs (vous pensiez probablement à char * ou char [] – ce sont des pointeurs eux-mêmes).
Scanf lit les entrées sur une adresse mémoire. a
est la valeur détenue par a. &a
est l’emplacement d’ a
en mémoire.
Dans votre code ci-dessus, le c
devrait être &c
.
Parce que scanf()
besoin de pointeurs, et &a
est le pointeur sur un entier.
Dans votre exemple, vous avez besoin d’une virgule et d’une esperluette devant le c
.
int main(void) { int a; char c; char s[21]; scanf("%d",&a); scanf("%c", &c); // Fixed! scanf("%20s", s); printf("a = %d, c = %c, s = <<%s>>\n", a, c, s); }
Si vous lisiez une chaîne, vous passeriez la chaîne – un pointeur sur char – vers scanf()
.
Vous devez fournir à scanf un pointeur, c’est pourquoi vous avez & in scanf (“% d”, & a) ; . scanf (“% c” c) ; ne fonctionnera pas du tout.
Votre exemple est faux. Si tu as un
char c;
alors vous devez append un &
au nom lorsque vous appelez scanf
:
scanf("%c", &c);
Cependant , si votre variable est déjà un pointeur, par exemple parce que c’est un caractère char[]
(qui est une syntaxe élégante pour les pointeurs), vous devez omettre le &
.
J’aime penser à l’esperluette (&) comme “adresse de”. Donc, vous lisiez &a
comme “adresse d’un”.
De plus, j’ai essayé de le comstackr mais il m’a averti sur gcc:
Warning: format "%c" expects type 'char *', but argument 2 has type 'int'
Ce qui est vrai, car un caractère est fondamentalement un int.