2010-10-02 5 views
1

donc mon code a en elle les suivantes:Conversion à court de char, résultats impairs?

unsigned short num=0; 
num=*(cra+3); 
printf("> char %u\n",num); 

cra est un char *

Le problème est qu'il devient sortie étrange, sortie parfois des nombres tels que 65501 (clairement pas dans la gamme d'un omble). Des idées?

Merci d'avance!

+1

pour que votre code soit valide cra doit être un pointeur. Pouvez-vous nous montrer sa déclaration? –

+0

Quel est le contenu de cra? – Ruel

Répondre

6

Apparemment *(cra+3) est un char de valeur '\xdd'. Puisqu'un char est signé, cela signifie en fait -35 (0xdd dans le complément 2), c'est-à-dire 0x ... fffffdd. La restriction ce à 16 bits donne 0xffdd, à savoir 65501.

Vous devez faire un unsigned char il donne un certain nombre dans la gamme 0-255:

num = (unsigned char)cra[3]; 

Note:
1. la signature de char est définie par l'implémentation, mais généralement (par exemple dans le cas d'OP) elle est signée.
2. les plages de signed char, unsigned char et unsigned short sont définies par l'implémentation, mais là encore, elles sont généralement de -128-127, 0-255 et 0-65535 respectivement.
3. la conversion de signed char à unsigned char est en fait -35 + 65536 = 65501.

+1

Un 'char' peut également être non signé. Dans ce cas, ce n'est pas le cas, mais en général il le peut. –

+2

Si le char avait vraiment la valeur * 0xdd, qui est 221, alors il resterait simplement comme 221 lorsqu'il est converti en 'short non signé '. Il a probablement la valeur -35 (qui dans le complément à deux aurait la même représentation que la valeur 8 bits non signée '0xdd'). – caf

+0

@caf: excellent point sur * value * versus * representation *. –

0

cra est juste un pointeur.

Aucun espace n'a été attribué, par l'intermédiaire de malloc ou calloc. Donc, son contenu est indéfini. *(cra + 3) évaluera au contenu de l'emplacement 3 octets en avance de l'emplacement cra (en supposant que char occupe 1 octet). Je crois que son contenu est également indéfini.

unsigned short prend 2 octets, au moins sur mon système. Par conséquent, il peut contenir des valeurs de 0 à 65536. Ainsi, votre sortie est dans sa plage définie

2

char est autorisé à être signé ou non signé - apparemment, sur votre plate-forme, il est signé.

Cela signifie qu'il peut contenir des valeurs telles que -35. Une telle valeur ne se situe pas dans la plage représentable par unsigned short. Lorsqu'un nombre hors plage est converti en un type non signé, il est amené dans la plage en ajoutant ou en soustrayant de façon répétée un chiffre de plus que la valeur maximale représentable dans ce type.

Dans ce cas, votre unsigned short peut représenter des valeurs jusqu'à 65535, donc -35 est mis en gamme en ajoutant 65536, ce qui donne 65501.

+1

@Hogan: Cela ne dépend pas vraiment de la représentation interne des nombres - c'est la façon dont C est spécifié pour fonctionner, indépendamment de la représentation interne. C'est un no-op sur les machines à complément à deux, mais les implémentations de type sign-magnitude et celles de complément doivent faire un travail supplémentaire sur les conversions signées-non signées pour être correctes. – caf

0

court non signé a une portée de (au moins) 0 ..65535 (link), le % u spécificateur format imprime un unsigned int avec une gamme de (généralement) 0 .. 4294967295. Ainsi, en fonction de la valeur de cra, la sortie semble être complètement sensible.

Questions connexes