2010-04-16 16 views
6

Heute fand ich folgendes:Multipliziert char und int zusammen in C

#include <stdio.h> 

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

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

return 0; 

} 

Also im Grunde ein Überlauf Ich erhalte, weil die Größenbegrenzung durch die Operanden auf der rechten Seite von dem = -Zeichen bestimmt wird ??

Warum wirft es nicht vor der Multiplikation auf int?

In diesem Fall verwende ich ein char und int, aber wenn ich "long" und "long long int" (c99) verwende, dann bekomme ich ähnliches Verhalten. Wird generell davon abgeraten, mit Operanden unterschiedlicher Größe arithmetisch zu arbeiten?

Antwort

11

char kann entweder mit oder ohne Vorzeichen, auf Ihrem Compiler abhängig.

In Ihrem Fall scheint es signiert zu sein, und 255 liegt außerhalb des Bereichs, den es darstellen kann (wahrscheinlich kann es nur Zahlen von -128 bis 127 darstellen).

Das Problem tritt also auf, wenn Sie 255 zu Ihrer char Variable zuweisen - dies führt zu einem implementierungsdefinierten Wert, der in Ihrem Fall -1 zu sein scheint.

Wenn Sie -1 mit 2 multiplizieren, erhalten Sie -2. Kein Geheimnis dort. Die Besetzung zu (int) tut nichts - Typen schmaler als int werden immer zu int oder unsigned int befördert, bevor irgendwelche Berechnungen mit ihnen erfolgt sind.

4

Nein, Sie erhalten keinen Überlauf in der zweiten Zeile (Multiplikation). Das Problem ist, dass Ihr Compiler standardmäßig signed char und 255 Überläufe verwendet und -1 bedeutet. Grundsätzlich initialisieren Sie die Variable x mit dem Wert -1. Wenn -1 an int übergeben wird, ergibt dies -1 (signed Operanden werden in Upcasts vorzeichenerweitert, während unsigned Operanden null-erweitert werden).

können Sie die char zwingen, zu sein unsigned durch Zugabe des unsigned Präfix:

unsigned char x = 255; 
5

Es scheint, dass char auf Ihrer Plattform unterzeichnet ist. So ist das char x = 255 effektiv das gleiche wie char x = -1. Die Besetzung von int spielt keine Rolle.

Versuchen Sie, dass an sich ändernde:

unsigned char x = 255; 
3

Die anderen Antworten erklären schön, wie Ihr Beispiel "funktioniert", also werde ich das nicht noch einmal erklären.

Lassen Sie mich jedoch beobachten, dass wenn das, was Sie ein „unsigned 8-Bit-Integer“ verwenden möchten, nur uint8_t bereits <stdint.h> ‚s verwenden (und seine 16, 32, 64-Bit-Begleiter) und halten Sie weg von allen char s , short s und int s in dieser Welt.

+1

# enthalten für diese Typen. – slartibartfast