Как я могу сравнить char с int?

Я не очень хорошо знаком с C, поэтому я немного запутался в безопасности типов языка.

Например.

char* my_pointer;

my_pointer = malloc(sizeof(char));

if (*my_pointer == 0b0000)
{
    // this might be true or false, doesn't matter
}

Почему код работает? Почему бы просто не взорваться в *my_pointer == 0b0000?

Разве *my_pointer не должен возвращать символ?

Так что технически не должно работать только что-то вроде *my_pointer == 'a'?


person AlanSTACK    schedule 02.02.2018    source источник
comment
когда вы разыменовываете my_pointer, вы получаете char, но затем он повышается до int, то же самое происходит с другим значением   -  person Martin Chekurov    schedule 02.02.2018
comment
@martin Вау, я думаю, ты что-то понял. К сожалению, поскольку я новичок в C, возможно, более подробное объяснение того, что вы упомянули, было бы ответом, который я бы с радостью принял.   -  person AlanSTACK    schedule 02.02.2018
comment
Стандартные правила C здесь неприменимы, поскольку двоичные целочисленные константы 0b0000 не являются частью языка.   -  person user694733    schedule 02.02.2018
comment
SO не может заменить курс для начинающих. Вы должны взять учебник C и узнать об основных типах и правилах преобразования.   -  person Gerhardh    schedule 02.02.2018
comment
Правила повышения неявного типа   -  person Lundin    schedule 02.02.2018
comment
Интересно, что 'a' также является int. Почему sizeof('a') равен 4 в C?   -  person Bo Persson    schedule 02.02.2018


Ответы (3)


Язык C не имеет специального «символьного» типа с некоторой изолированной «только символьной» семантикой. char — это просто еще один целочисленный тип в C, точно так же, как short или int. Просто это самый маленький целочисленный тип. Вы можете использовать char для целочисленных арифметических вычислений точно так же, как и любой другой целочисленный тип (хотя использование char в этой роли — не очень хорошая идея).

Когда вы сравниваете char и int, вы просто сравниваете два целочисленных значения. В этом нет ничего необычного.

Правила преобразования целых чисел говорят, что char неявно преобразуется в int (при условии, что диапазон подходит), а затем сравниваются два значения int.

Ваш пример *my_pointer == 'a' на самом деле ничем не отличается от исходного. В C 'a' — это символьная константа, представляющая целочисленное значение типа int. т.е. нет необходимости даже повышать 'a' до int, так как это уже int.

person AnT    schedule 02.02.2018
comment
Происходит ли целочисленное продвижение для всех встроенных типов переменных в C? - person AlanSTACK; 02.02.2018
comment
@AlanSTACK: целочисленное продвижение происходит с небольшими целочисленными типами [signed/unsigned] char и [signed/unsigned] short в тех контекстах, где спецификация языка говорит, что это должно происходить. Оператор == оказывается одним из таких контекстов. - person AnT; 02.02.2018

Прежде всего, 0b не является допустимым стандартным префиксом C для целочисленных констант. Поэтому вам нужно убедиться, что вы следуете особенностям используемой вами платформы.

При этом, согласно правилам для операторов равенства (==), правила арифметического преобразования (целочисленного преобразования) применимы к операндам, если оба они имеют арифметический тип.

Цитирование C11, глава §6.5.9,

Если оба операнда имеют арифметический тип, выполняются обычные арифметические преобразования. [...]

person Sourav Ghosh    schedule 02.02.2018

Вы просто сравниваете 2 целочисленных значения. Это происходит потому, что 0b0000 является целочисленным литералом, а значение, которое вы получаете после разыменования my_pointer, повышается до int.

Если int может представлять все значения исходного типа, значение преобразуется в int; в противном случае он преобразуется в беззнаковое целое число

person Martin Chekurov    schedule 02.02.2018