68 votes

Pourquoi dois-je spécifier un type de données à chaque fois en C?

Comme vous pouvez le voir dans l'extrait de code ci-dessous, j'ai déclaré un char variable et un int variable. Lorsque le code est compilé, il doit définir les types de données des variables str et i.

Pourquoi ai-je besoin de le dire à nouveau au cours de la numérisation ma variable que c'est une chaîne de caractères ou variable de type entier en spécifiant %s ou %d de scanf? N'est-ce pas le compilateur assez mature pour identifier que quand j'ai déclaré mes variables?

#include <stdio.h>

int main ()
{
  char str [80];
  int i;

  printf ("Enter your family name: ");
  scanf ("%s",str);  
  printf ("Enter your age: ");
  scanf ("%d",&i);

  return 0;
}

122voto

Yu Hao Points 40603

Car il n'y a pas de portable voie à une variable en argument des fonctions comme scanf et printf de connaître le type de la variable d'arguments, même pas le nombre d'arguments passés.

Voir C FAQ: Comment puis-je découvrir combien d'arguments d'une fonction est en fait appelé?


C'est la raison, il doit être d'au moins l'un fixe, l'argument de déterminer le nombre, et peut-être les types de variable d'arguments. Et cet argument (la norme exige que c' parmN, voir C11(ISO/IEC 9899:201x) §7.16 Variable d'arguments ) joue ce rôle spécial, et sera transmis à la macro va_start. En d'autres mots, vous ne pouvez pas avoir une fonction avec un prototype de ce genre dans la norme C:

void foo(...);

28voto

Devolus Points 10549

La raison pourquoi le compilateur ne peut pas fournir l'information nécessaire est tout simplement, parce que le compilateur n'est pas en cause ici. Le prototype des fonctions ne précise pas les types, parce que ces fonctions ont des types de variables. Si les types de données réels ne sont pas déterminés au moment de la compilation, mais au moment de l'exécution. La fonction prend un argument à partir de la pile, après les autres. Ces valeurs n'ont pas de n'importe quel type d'information associés avec elle, de sorte que la seule façon, la fonction sait comment interpréter les données, en utilisant l'appelant a fourni de l'information, qui est la chaîne de format.

Les fonctions elles-mêmes ne savent pas quels types de données sont transmises, et ne savent pas le nombre d'arguments passés, il n'existe aucun moyen qu' printf peut décider de cela sur son propre.

En C++, vous pouvez utiliser la surcharge d'opérateur, mais c'est tout un mécanisme différent. Car ici, le compilateur choisit la fonction appropriée en fonction du type de données disponibles et fonction surchargée.

Pour illustrer ceci, printf, lors de la compilation ressemble à ceci:

 push value1
 ...
 push valueN
 push format_string
 call _printf

Et le prototype de l' printf est-ce:

int printf ( const char * format, ... );

Donc, il n'y a pas d'informations de type reporté, à l'exception de ce qui est prévu dans la chaîne de format.

14voto

Tarik Points 3304

printf n'est pas une fonction intrinsèque. Il ne fait pas partie du langage C en soi. Tout le compilateur n'est de générer du code pour appeler printf, passant quels que soient les paramètres. Maintenant, parce que C ne fournit pas de réflexion , comme un mécanisme pour déterminer des informations de type à l'exécution, le programmeur a explicitement de fournir l'information nécessaire.

13voto

mvp Points 29360

Le compilateur est peut-être intelligent, mais les fonctions printf ou scanf sont stupides - ils ne savent pas quel est le type de paramètre que vous transmettez pour chaque appel. C'est pourquoi vous devez passer %s ou %d chaque fois.

10voto

Kos Points 29125

Le premier paramètre est une chaîne de format. Si vous avez l'impression d'un nombre décimal, il peut ressembler à:

  • "%d" (nombre décimal)
  • "%5d" (nombre décimal collier de largeur 5 avec des espaces)
  • "%05d" (nombre décimal collier de largeur 5 avec des zéros)
  • "%+d" (nombre décimal, avec toujours un signe)
  • "Value: %d\n" (un peu de contenu avant/après le nombre)

etc, voir, par exemple, le Format des espaces réservés sur Wikipédia pour avoir une idée de ce que les chaînes de format peut contenir.

Il peut aussi y avoir plus d'un paramètre ici:

"%s - %d" (une chaîne de caractères, puis une partie du contenu, du nombre)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X