В следующем примере выводится битовое представление byte со всеми единицами:
#include <stdio.h>
int main (void)
{
char c = 255;
char z;
for (int i = 7; i >= 0; i--) {
z = 1 << i;
if ((z & c) == z) printf("1"); else printf("0");
}
printf("\n");
return 0;
}
Выход 11111111
Теперь мы меняем char c на int c, чтобы пример стал таким:
#include <stdio.h>
int main (void)
{
int c = 255;
char z;
for (int i = 7; i >= 0; i--) {
z = 1 << i;
if ((z & c) == z) printf("1"); else printf("0");
}
printf("\n");
return 0;
}
Теперь выход 01111111.
Почему выход другой?
ОБНОВЛЕНИЕ
Скомпилируйте следующее test.c:
#include <stdio.h>
int main(void)
{
char c=-1;
printf("%c",c);
return 0;
}
$ gcc test.c
$ ./a.out | od -b
0000000 377
0000001
Вывод 377, что означает, что glibc противоречит gcc, потому что подписанный символ автоматически преобразуется в беззнаковый. Почему такие сложности? Разумно иметь char без знака по умолчанию. Есть какая-то конкретная причина, почему нет?
stdint.h. И при смещении, как правило, лучше использовать беззнаковые типы, потому что определенные сдвиги/значения для целых чисел со знаком определяются реализацией или даже вызывают неопределенное поведение. - person too honest for this site   schedule 08.11.2016