Буквальный символ в C: это int или char?

Если я объявляю это:

int i = 0 + 'A';

'A' считается char или int?

некоторые люди могут использовать:

int i = 0 + (int)'A';

но действительно ли это необходимо?

Ответ 1

В C символьные константы, такие как 'A', имеют тип int. В С++ они имеют тип char.

В C тип символьной константы редко имеет значение. Он должен быть int, но если язык был изменен, чтобы сделать его char, большинство существующих кодов продолжали бы работать должным образом. (Код, который явно ссылается на sizeof 'A', изменит поведение, но в письменной форме не так много смысла, если вы не пытаетесь отличить C и С++, и есть более надежные и надежные способы сделать это. Есть случаи, связанные с макросами где sizeof 'A' может быть разумным, я не буду вдаваться в подробности здесь.)

В вашем примере кода:

int i = 0 + 'A';

0 имеет тип int, а два операнда + продвигаются, если необходимо, к общему типу, поэтому поведение абсолютно одинаково в любом случае. Даже это:

char A = 'A';
int i = 0 + A;

делает то же самое, при A (который имеет тип char) продвигается до int. Выражения типа char обычно, но не всегда, неявно продвигаются до int.

В С++ символьные константы имеют тип char - но применяются те же правила продвижения. Когда Stroustrup проектировал С++, он изменил тип символьных констант для согласованности (по общему признанию, это немного удивительно, что A имеет тип int) и позволяет более последовательно перегружать (что C не поддерживает). Например, если константы символов С++ имеют тип int, то это:

std::cout << 'A';

будет печатать 65, значение ASCII 'A' (если только система не использует EBCDIC); для него имеет смысл печатать A.

int i = 0 + (int)'A';

Приведение не требуется в C и С++. В C, 'A' уже имеет тип int, поэтому преобразование не влияет. В С++ это тип char, но без трансляции он будет неявно преобразован в int в любом случае.

Как в C, так и в С++, приведения следует рассматривать с подозрением. Оба языка предоставляют неявные преобразования во многих контекстах, и эти преобразования обычно делают правильные вещи. Явное литье либо переопределяет неявное преобразование, либо создает преобразование, которое иначе не имело бы места. Во многих случаях (но отнюдь не всех) бросок указывает на проблему, которая лучше решается либо с помощью неявного преобразования, либо с помощью изменения объявления, так что преобразованная вещь имеет нужный тип в первую очередь.

(Поскольку Паскаль Куок напоминает мне в комментариях, если plain char не имеет знака и шириной, как int, то выражение типа char будет продвигаться до unsigned int, а не до int. может произойти только в том случае, если CHAR_BIT >= 16, т.е. если реализация имеет 16-битные или более большие байты, а если sizeof (int) == 1, и если plain char не подпадает под подпись. Я не уверен, что такие реализации действительно существуют, хотя я что компиляторы C для некоторых DSPs имеют CHAR_BIT > 8.)

Ответ 2

В C, 'A' тип int (не char). Я думаю, что некоторые люди делают int i = 0 + (int)'A'; в С++ (или делают код полезным как в С++/C).

Ответ 3

В соответствии со стандартом ISO C99 тип буквенного символа в C int.

Однако, буквальные символы, такие как 'c', имеют диапазон, который соответствует char.
Таким образом, вы можете назначить буквенный символ переменной char без потери информации.

 char c = 'c'; /* 'c' is int, but (c == 'c') is true */