0
votes

Ambiguïté en C avec Printf

Pourquoi le langage C agit-il comme ceci

1,1
2,2
3,3

La sortie est

#include <stdio.h> 
#include <stdlib.h> 
int main()
{
 const int size = 3;
 double a[size];
 for(int n=0; n<size; ++n){
   a[n] = n;
   printf("%d,%d\n",a[n],n+1); //change is here
 }
}

Mais quand je fais cela

0,1 
1,2 
2,3

Le résultat est:

#include <stdio.h> 
#include <stdlib.h> 
int main()
{
 const int size = 3;
 double a[size];
 for(int n=0; n<size; ++n){
   a[n] = n;
   printf("%d,%d\n",n,n+1);
 }
}

Pourquoi la valeur change-t-elle simplement en remplaçant n et a [n] qui sont les mêmes?

c

0 commentaires

3 Réponses :


6
votes

a [n] est un double, que vous ne pouvez pas imprimer avec% d


3 commentaires

Techniquement, on peut imprimer un double avec % d , mais le comportement n’est pas défini par la norme. Une implémentation devrait spécifier ce comportement. Mais je ne suis au courant d'aucune implémentation qui fasse cela.


@RobertSsupportsMonicaCellio Techniquement, on peut essayer d'imprimer un double avec% d


@ user253751 Oui, c'est ce que je voulais dire aussi. Celui peut ou essayer tout ce qu’il veut, mais le comportement n’est pas défini. :-)



1
votes

La raison est due au fait que dans la seconde, vous essayez d'imprimer un [n] qui est un double en utilisant % d spécification de format, qui est pour int , résultant en un comportement indéfini.

Par exemple, dans mon système, je reçois ceci imprimé:

clang-7 -pthread -lm -o main main.c
main.c:9:21: warning: format specifies type 'int' but the argument has type
      'double' [-Wformat]
   printf("%d,%d\n",a[n],n+1); //change is here
           ~~       ^~~~
           %f
1 warning generated.

Le compile devrait vous en avertir. C-lang vous en donne un:

1,1559556488
2,1559554816
3,1559554816


0 commentaires

1
votes

" Pourquoi la valeur change-t-elle simplement en remplaçant n et a [n] qui sont identiques "

Lorsque vous utilisez printf ("% d,% d \ n", a [n], n + 1); dans le deuxième exemple, le deuxième argument ( a [n ] ) est de type double , alors que dans le premier exemple n est de type int .

Le fait d'utiliser n de type int comme index ne rend pas l'objet double adressé de type int .

Pour utiliser le spécificateur de conversion % d pour imprimer une valeur double , on appelle comportement indéfini .

Le standard C stipule:

d, i L'argument int est converti en décimal signé dans le style [-] dddd. La précision spécifie le nombre minimum de chiffres à afficher; si la valeur en cours de conversion peut être représentée en moins de chiffres, elle est développée avec des zéros non significatifs. La précision par défaut est 1. Le résultat de la conversion d'une valeur zéro avec une précision de zéro est sans caractère.

Source: C18, 7.21.6.1/8

et

Si une spécification de conversion n'est pas valide, le comportement n'est pas défini.288) Si un argument n'est pas du type correct pour la spécification de conversion correspondante, le comportement n'est pas défini .

Source: C18, 7.21.6.1/9


0 commentaires