Impression d’éléments de tableau

Le résultat attendu du programme C suivant est d’imprimer les éléments du tableau. Mais quand effectivement couru, il ne le fait pas.

#include #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16}; int main() { int d; for(d=-1;d <= (TOTAL_ELEMENTS-2);d++) printf("%d\n",array[d+1]); return 0; } 

Quelle est la raison ?

Lorsque vous effectuez la comparaison d <= (TOTAL_ELEMENTS-2) , une conversion de type est effectuée. d est du type signed int tandis que (TOTAL_ELEMENTS-2) est du type size_t , qui est un type non signé. Les règles de C disent que lorsqu'un opérateur a un argument signé et un argument non signé, et que l'argument non signé est d'une taille supérieure ou égale à l'argument signé, alors l'argument signé est converti en non signé.

C'est-à-dire que la comparaison se termine comme suit:

 (size_t) d <= (TOTAL_ELEMENTS-2) 

Et parce que size_t n'est pas signé, (size_t) -1 est un très très grand nombre, pas -1 plus. Pour une size_t 32 bits, il faudrait 2 32 - 1 = 4 294 967 295.

Pour résoudre ce problème, vous pouvez explicitement convertir le côté droit en entier signé:

 d <= (int) (TOTAL_ELEMENTS-2) 

Ou mieux encore, débarrassez-vous de l'indexation négative étrange, etc.

Pour référence future, activez tous les avertissements du compilateur que vous pouvez. gcc, par exemple, affichera un avertissement si vous activez -Wall -Wextra :

 $ gcc -o arrayprint -Wall -Wextra -ansi arrayprint.c arrayprint.c: In function 'main': arrayprint.c:11: warning: comparison between signed and unsigned 

TOTAL_ELEMENTS n’est pas signé. -1, une fois converti en non signé, est un nombre vraiment énorme, qui n’est pas inférieur à 6. Ainsi, votre boucle ne s’exécute jamais.

Au début, je ne savais pas. Mais lorsque je l’ai compilé avec GCC, il était évident:

 $ gcc -Wall -Wextra -Os ac ac: In function `main': ac:11: warning: comparison between signed and unsigned 

Donc, vous avez une comparaison comme suit:

 (int) -1 <= (size_t) 5 

Étant donné que l'un des types est signé et l'autre non signé, ils doivent d'abord être convertis en un type commun. Dans ce cas, il s'agit de size_t . Cela le rend:

 (size_t) -1 <= (size_t) 5 

Maintenant, -1 ne peut pas être représenté dans un type non signé. Par conséquent, 2 ^ 32 (ou le nombre de bits dont size_t a) sont ajoutés, ce qui en fait le numéro 4294967295. La comparaison est donc la suivante:

 4294967295 <= 5 

Et c'est false , donc le corps de la boucle n'est jamais exécuté.

La raison en est que la boucle n’est jamais exécutée. En effet, TOTAL_ELEMENTS retourne un size_t, un type non signé.

Vous pouvez résoudre ce problème en (TOTAL_ELEMENTS-2) en un entier.

Vous devez faire ce qui suit:

 for(d=0;d < TOTAL_ELEMENTS;d++) printf("%d\n",array[d]); 

comme sizeof(...) produit une valeur non signée.

Il suffit de changer

 #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) 

Avec

 #define TOTAL_ELEMENTS (int)(sizeof(array)/sizeof(array[0]))-2