проблема со знаком char c ++ - PullRequest
3 голосов
/ 19 января 2011

Это код:

int main()
{

 char c = 0x00;
 //c |= 0x0A;
 c |= 0xA0;

 while(c != 0x00)
 {
  cout << (c & 1) << endl;
  c = (c >> 1); 
 }
}

Почему этот код работает, когда я выполняю or с 0X0A, а не с 0xA0, поскольку число 0xA0 слишком велико, чтобы соответствовать знаковому символу, но почему я не могу установить биты для 0xA0?

Когда я печатаю петлю, она никогда не разрывается и только печатает? Как получилось?

Ответы [ 2 ]

4 голосов
/ 19 января 2011

Это из-за расширения знака при выполнении правого сдвига.

0xA0 <=>        10100000 binary (and is a negative number because the MSB is set to 1)
(0xA0 >> 1) <=> 11010000

замените char c на unsigned char c или замаскируйте MSB после сдвига.

int main()
{

 char c = 0x00;
 //c |= 0x0A;
 c |= 0xA0;

 while(c != 0x00)
 {
  cout << (c & 1) << endl;
  c = (c >> 1) & 0x7f; 
 }
}

Обратите внимание, что char обычно является знаком (диапазон -128..127), но некоторые компиляторы c / C ++ определяют char как unsigned (компилятор AIX xlC известен).

1 голос
/ 19 января 2011

Ваша реализация должна добавить 1 в старшем значащем бите при смещении вправо отрицательного числа (поведение оператора определяется реализацией, поэтому обычно зависит от того, какие инструкции процессора доступны).

0xA0 = 1010 0000 binary

первый раз, когда вы производите выборку c & 1 - младший значащий бит - на самом деле это 0. Затем ...

c = (c >> 1)

... сдвигает это значение до 1101 0000, затем 1110 1000, 1111 0111, 1111 1011,1111 1101, 1111 1110, 1111 1111 - который тогда стабилен и никогда не меняется дальше.Следовательно, вы продолжаете печатать 1 с и никогда не удовлетворяете условию завершения c == 0.

Когда я печатаю цикл, он никогда не прерывается и только печатает?Как получилось?

Ну, в самом начале он напечатает несколько нулей, но ваш экран, вероятно, прокручивается мимо них в мгновение ока, и после этого вы видите только 1.

...