2010-07-30 13 views
8
#include <stdio.h> 
int main() 
{ 
    unsigned char i=0x80; 
    printf("%d",i<<1); 
    return 0; 
} 

Dlaczego ten program drukuje 256?Maksymalna wartość unsigned char

Jak to zrozumieć, ponieważ 0x80 = 0b10000000 i unsigned char ma 8 bitów, „1” powinna przelania po przesunięcie w lewo, a wyjściowy powinien wynosić 0, a nie 256.

+2

Nie chcę publikować jako odpowiedzi, ponieważ nie jestem w 100% pewny, ale czy to nie dlatego, że% d jest liczbą całkowitą? Zatem kod za scenami prawdopodobnie przypisuje "i << 1" do liczby całkowitej, aby ją wydrukować, co oznacza, że ​​pasuje i nie przepełnia się. Spróbuj zrobić "printf ("% c ", i << 1);'? – Stephen

+0

@Stephen: Powinien opublikować odpowiedź;) – KevenK

+0

@Stephen: Dane wyjściowe są puste, gdy używam% c. – Variance

Odpowiedz

14

Wynika to z C na zasady dotyczące liczby całkowitej. Zasadniczo większość zmiennych wchodzących w wyrażenie jest "promowana", więc takie operacje nie tracą precyzji. Następnie jest przekazywana jako int do printf, zgodnie z regułami zmiennych argumentów C.

Jeśli tylko chcesz, co szukasz, trzeba oddać z powrotem do unsigned char:

#include <stdio.h> 
int main() 
{ 
    unsigned char i=0x80; 
    printf("%d",((unsigned char)(i<<1))); 
    return 0; 
} 

Uwaga: Używanie %c jak podano w komentarzu Stefana nie zadziała, ponieważ oczekuje %c również liczba całkowita.

EDIT: Ewentualnie, można to zrobić:

#include <stdio.h> 
int main() 
{ 
    unsigned char i=0x80; 
    unsigned char res = i<<1; 
    printf("%d",res); 
    return 0; 
} 

lub

#include <stdio.h> 
int main() 
{ 
    unsigned char i=0x80; 
    printf("%d",(i<<1) & 0xFF); 
    return 0; 
} 
+0

Czy możesz rzucić '(i << 1)' na 'unsigned char'? – nmichaels

+0

@Nathon: Czy to nie to, co zrobiłem? –

+1

Dziwne, muszę mieć włączone zasłony. – nmichaels

0

Nie zapomnij formatu specjalnie do drukowania bez znaku.

printf("%u",(unsigned char)(i<<1)); 
+0

Z powodu zasad promocji C, argument zostanie najprawdopodobniej przekazany do' printf' jako 'signed int', nie' unsigned 'Należy rzucić argument do typu, który pasuje do specyfikatora formatu. –