Проблемы здесь:
char charray[] = {0xAA, 0x00, 0x02};
Тип CHAR имеет определенную реализацию знаковости, а это означает, что в некоторых системах это будет эквивалентно signed char
. A signed char
может хранить только значения до 0x7F, и MSB будет обрабатываться как знаковый бит. Это то, что происходит в вашем случае, 0xAA
преобразуется в значение со знаком -86
(оно определяется реализацией, какое значение оно получает, я предполагаю дополнение двух).
Знак затем сохраняется в выражении 0xAA == ch
, так как ch
затем подлежит произведению типа int
и знак сохраняется. Это означает, что вы фактически будете сравнивать 0xAA == -86
, что является ложным.
Чтобы избежать таких ошибок, всегда используйте uint8_t
при выполнении любой формы арифметики на уровне байта.
Нет, он фактически сравнивает '0xAA == -86'. Не обязательно то же самое, что и '0xAA == 0xFFFFFFAA', в зависимости от того, как неявные рекламные акции оказываются в конкретной системе. – Lundin
@ Lundin, если вы хотите быть придирчивым, он фактически сравнивает '0xAA == (signed char) 0xAA', который даже отличается, поскольку преобразование определяется реализацией. – ouah
Моей точкой является то, что левый операнд (int literal) является «int», тогда char будет проходить только целую рекламу (целое правило продвижения) и оставаться подписанным. Но если литерал был неподписанным типом, также была бы балансировка (обычные арифметические преобразования), и правый операнд также преобразуется в неподписанный тип. В этом случае вы на самом деле оказываетесь равным «0xFFFFFFAAu». Но этого не происходит в этом конкретном примере. – Lundin