web-dev-qa-db-fra.com

différence entre imprimer 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.

12
ipkiss

%u traite l'entier comme non signé, alors que %d traite l'entier comme signé. Si le nombre entier est compris entre 0, un INT_MAX (qui est 231-1 sur les systèmes 32 bits), la sortie est identique dans 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 231 et 232-1). Dans ce cas, si vous utilisez le spécificateur %d, vous obtiendrez un nombre négatif, alors que si vous utilisez %u, vous obtiendrez 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 - il est garanti que cela fonctionne 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é et toute autre chose imprimée plus tard (car printf n'a lu que 4 des 8 octets de l'argument du pointeur); Si vous ajoutez le modificateur de longueur ll, vous ne serez pas portable pour les systèmes 32 bits.

Ligne de fond: 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 avec un 0x en tête.

38
Adam Rosenfield

%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.

1
Raph Levien

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 ont la même apparence que les valeurs non signées. 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 paraît), utilisez% p à la place.

0
Jonathan Wood

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.

0
steveo225

Il n’existe pas de différence de ce type, mais ne vous perdez pas en confusion si vous venez de commencer à apprendre les pointeurs. % U est réservé aux non-signés.Et% d, aux signés

0
Faraz Malik