Этот код печатает -56
и я не знаю, почемуМожет кто-нибудь сказать мне, почему эта программа печатает -56?
#include<stdio.h>
main()
{
printf("%d\n", ((int)(char)200));
}
Этот код печатает -56
и я не знаю, почемуМожет кто-нибудь сказать мне, почему эта программа печатает -56?
#include<stdio.h>
main()
{
printf("%d\n", ((int)(char)200));
}
Поскольку char
неявно signed char
на вашей платформе.
ли
printf("%d\n", ((int)(unsigned char)200));
получить
200
Число 200 находится вне диапазона значений для signed char
. Он обертывается в отрицательный диапазон значений в дополнении друг к другу.
Очевидно, что (подразумеваемая) подпись char
определена на вашей платформе signed
. Обратите внимание, что это не предусмотрено стандартом. Если бы это было unsigned
, ваша программа будет печатать 200. Для дальнейшего чтения по этой теме:
Очевидно, что размер char
типа 8 бит на вашей платформе. Определение этой величины также не указано в спецификации языка. Если бы он был больше, программа может очень хорошо напечатать 200, как и ожидалось. Для дальнейшего чтения по этой теме:
Также обратите внимание, что это не определен стандартом, что целые типы должны использовать дополнение двоичного представления в двоичном. На другой платформе отливка может даже дать совершенно другой результат. Для дальнейшего чтения:
Но OP использует 'char', а не' signed char'. Подписанность 'char' определяется реализацией, поэтому этот ответ не является полным. – Lundin
Не думаю, что http://stackoverflow.com/q/17045231/1025391 должно быть указано для объяснения «приведение может даже привести к совершенно другому результату». Связанный вопрос касается представлений. Семантика приведения к 'T1' значения типа' T2' не должна иметь ничего общего с представлением 'T1' или' T2'. –
@PascalCuoq Я нашел лучшую ссылку сейчас, я думаю. – moooeeeep
char
является signed
и int
является signed
(по умолчанию на вашей платформе).
(signed char)11001000
= -56 десятичного
(signed int)0000000011001000
= 200 десятичное
Посмотрите Signed number representations
Совсем нет. char подписывается, поэтому, когда компилятор переходит к int, он выполняет расширение знака, поэтому 11001000 преобразуется в 11111111111111111111111111001000 (для 32-битного int) –
Это все еще неверно. 'char' подписан на его платформе, и поэтому' int'. – NaotaSang
Кроме того, шестнадцатеричные коды являются полными бессмысленными. Вы пытаетесь написать BCD или что-то еще? Или «BCH», я полагаю .. двоично-кодированный шестнадцатеричный? – Lundin
Тип char
противоречива по отношению к остальной части языка C, так как char
может быть либо подписанный, либо неподписанный. Стандарт C утверждает это как поведение, определяемое реализацией, что означает, что компилятор может реализовать его в любом случае. Ваш конкретный компилятор, похоже, реализует char
как равный signed char
.
Из-за вышеизложенного, char
никогда не должен использоваться ни для чего другого, кроме строк.Это неправильная практика для арифметических операций. Такой код опирается на поведение impl.defined.
Тип int
всегда равен signed int
. Это требуется по стандарту C.
Таким образом, на вашей конкретной системе код, который вы написали, равен: (signed int)(signed char)200
.
При попытке сохранить значение 200 в переменной, эквивалентной signed char
, она будет переполняться и интерпретируется как -56 (на системе дополнений двух).
Когда вы нанесли signed char
, содержащий -56, на номер signed int
, вы получите -56.
полукокс 8bits Подписанные от -128 ~ 127 так 200 находится вне диапазона значений
или еще лучше, 'Е ("% d \ п", 200);'. – Lundin
Или я полагаю, если вы в сумасшедшем настроении, 'printf (" 200 ");'. – Lundin