différence entre l’impression d’une adresse mémoire en utilisant% u et% d en C?

Je lis un livre C. Pour imprimer une adresse mémoire d’une variable, le livre utilise parfois:

printf("%u\n",&n); 

Parfois, l’auteur écrivait:

 printf("%d\n",&n); 

Le résultat est toujours le même, mais je ne comprends pas les différences entre les deux (je connais% u pour non signé).

Quelqu’un peut-il élaborer à ce sujet, s’il vous plaît?

Merci beaucoup.

%u traite l’entier comme non signé, alors que %d traite cet entier comme étant signé. Si le nombre entier est compris entre 0 et INT_MAX (ce qui correspond à 2 31 -1 sur les systèmes 32 bits), la sortie est identique pour les deux cas.

Cela ne fait de différence que si le nombre entier est négatif (pour les entrées signées) ou compris entre INT_MAX+1 et UINT_MAX (par exemple, entre 2 31 et 2 32 -1). Dans ce cas, si vous utilisez le spécificateur %d , vous obtenez un nombre négatif, tandis que si vous utilisez %u , vous obtenez un grand nombre positif.

Les adresses n’ont de sens que comme numéros non signés. Il n’ya donc aucune raison de les imprimer en tant que numéros signés. De plus, lorsqu’ils sont imprimés, ils sont généralement imprimés en hexadécimal (avec le spécificateur de format %x ), et non en décimal.

Vous devriez vraiment simplement utiliser le spécificateur de format %p pour les adresses, cela fonctionnera pour tous les pointeurs valides. Si vous êtes sur un système avec des entiers 32 bits mais des pointeurs 64 bits, si vous essayez d’imprimer un pointeur avec l’un des %d , %u ou %x sans le modificateur de longueur ll , vous obtiendrez un résultat erroné. pour cela et pour tout ce qui sera imprimé plus tard (car printf ne lit que 4 des 8 octets de l’argument du pointeur); si vous ajoutez le modificateur ll length, vous ne serez pas portable pour les systèmes 32 bits.

Conclusion: utilisez toujours %p pour imprimer des pointeurs / adresses:

 printf("The address of n is: %p\n", &n); // Output (32-bit system): "The address of n is: 0xbffff9ec" // Output (64-bit system): "The address of n is: 0x7fff5fbff96c" 

Le format de sortie exact est défini par l’implémentation (C99 §7.19.6.1 / 8), mais il sera presque toujours imprimé sous la forme d’un nombre hexadécimal non signé, généralement précédé de 0x .

%d et %u afficheront les mêmes résultats lorsque le bit le plus significatif n’est pas défini. Cependant, ce n’est pas du tout un code portable, et ce n’est pas un bon style. J’espère que votre livre est meilleur qu’il n’y paraît de cet exemple.

Quelle valeur as-tu essayé? La différence non signée / signée, comme vous l’avez dit. Alors qu’est-ce qu’il a fait et à quoi vous attendiez-vous?

Les valeurs signées positives ressemblent à celles non signées, alors puis-je supposer que vous avez utilisé une valeur plus petite pour tester? Qu’en est-il d’une valeur négative?

Enfin, si vous essayez d’imprimer l’adresse de la variable (telle qu’elle vous semble), utilisez% p à la place.

Toutes les adresses sont non signées 32 bits ou 64 bits selon la machine (impossible d’écrire sur une adresse négative). L’utilisation de% d n’est pas appropriée, mais fonctionnera généralement. Il est recommandé d’utiliser% u ou% ul.

Il n’y a pas une telle différence, mais ne vous trompez pas si vous venez juste de commencer à apprendre des pointeurs. % u est destiné aux non signés. Et% d aux signés.