Question

Aujourd'hui, je trouve ce qui suit:

#include <stdio.h>

int main(){
char x = 255;
int z = ((int)x)*2;

printf("%d\n", z); //prints -2

return 0;

}

Donc, fondamentalement, je reçois un dépassement parce que la limite de taille est déterminée par les opérandes sur le côté droit du signe = ??

Pourquoi ne pas à int avant de multiplier le travail?

Dans ce cas, j'utilise char et int, mais si je l'utilise « long » et « long int » (C99), puis-je obtenir un comportement similaire. Est-il conseillé généralement contre faire des calculs avec des opérandes de différentes tailles?

Était-ce utile?

La solution

char peut être signé ou non signé, selon votre compilateur.

Dans votre cas, il semble être signé, et 255 est en dehors de la plage, il peut représenter (probablement, il ne peut représenter des nombres -128 à 127).

Le problème se produit lorsque vous attribuez 255 à votre variable char -. Il en résulte une valeur définie de mise en œuvre, ce qui dans votre cas, semble être -1

Lorsque vous multipliez -1 par 2, vous obtenez -2. Pas de mystère là-bas. Le casting de (int) ne fait rien -. Types plus étroits que int sont toujours promus int ou unsigned int avant que les calculs sont faits avec eux

Autres conseils

Il semble que l'omble est signé sur votre plate-forme. Ainsi, le char x = 255 est effectivement le même que char x = -1. Le casting à int n'a pas d'importance.

Essayez de changer cela à:

unsigned char x = 255;

Non, vous ne recevez pas un débordement sur la deuxième ligne (multiplication). Le problème est que votre compilateur utilise signed char par défaut et 255 déversoirs et signifie -1. En gros, vous initialisez x variable avec la valeur de -1. Coulée -1 int entraînera -1 (signed opérandes s'extension de signe en upcasts tandis que opérandes unsigned auront zéro étendu).

Vous pouvez forcer le char être unsigned en ajoutant le préfixe unsigned:

unsigned char x = 255;

Les autres réponses expliquent bien comment votre exemple « oeuvres », je ne vais pas expliquer à nouveau.

Cependant, permettez-moi de souligner que si ce que vous voulez utiliser est un « entier non signé 8 bits », utilisez <stdint.h> de uint8_t déjà (et ses 16, 32, compagnons de 64bit) et tenir à l'écart de tous les chars, shorts et ints dans ce monde.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top