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

Почему эта программа печатает 256?Максимальное значение unsigned char

Как я понимаю это, так как 0x80 = 0b10000000 и неподписанный символ имеет 8 бит, то «1» должен перелив после того, как сдвиг влево, а выход должен быть 0, а не 256.

+2

Не хотите публиковать как ответ, потому что я не уверен на 100%, но разве это не потому, что% d является целым числом? Таким образом, код за кулисами, вероятно, присваивает 'i << 1' целому числу для его печати, что означает, что он подходит и не переполняется. Попробуйте сделать 'printf («% c », i << 1);'? – Stephen

+0

@ Stephen: Должен был отправить ответ;) – KevenK

+0

@Stephen: Выход пустой, когда я использую% c. – Variance

ответ

14

Это является результатом Кассиопеяне целые правила продвижения. По существу, большая часть любой переменной, входящей в выражение, «продвигается», так что такие операции не теряют точность. Затем он передается как int в printf, в соответствии с правилами переменных аргументов C.

Если вы хотите, что вы ищете, вы должны были бы бросить обратно unsigned char:

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

Примечание: с помощью %c, как указано в комментарии Стефана не будет работать, потому что %c ожидает целое число.

EDIT: Кроме того, вы можете сделать это:

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

или

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

Не могли бы вы наложить '(i << 1)' на 'unsigned char'? – nmichaels

+0

@Nathon: Разве это не то, что я сделал? –

+1

Странно, мне нужно, чтобы мои слепоты включились. – nmichaels

0

Не забудьте формат специально для печати без знака.

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

Из-за правил продвижения C аргумент, скорее всего, будет передан' printf' как 'signed int', а не' unsigned '. Вы должны применить аргумент к типу, который соответствует спецификатору формата. –

Смежные вопросы