Подтвердить что ты не робот

Int - 4 байта, но все же его можно сохранить в char, почему нет переполнения

Проверьте эту программу

#include<stdio.h>

int main (){

char c='a';
printf("%d %d", sizeof(c),sizeof('a'));
}

вывод 1 4
Я знаю, когда мы пишем оператор char c = 'a';

то как получается, что в пространстве 1 байт (char c) сохраняется какая-то 4 байта (ASCII-код), почему нет переполнения и т.д.

4b9b3361

Ответ 1

Во-первых, согласно ANSI/IEC 9899: 1999 (E) §6.4.4.4:

  10. Целочисленная символьная константа имеет тип int. Значение целочисленной символьной константы содержащий один символ, который сопоставляется однобайтовому символу выполнения, является числовое значение представления отображаемого символа, интерпретируемого как целое число. [...]

§6.5.3.4:

  2. Оператор sizeof дает размер (в байтах) своего операнда, который может быть выражение или имя в скобках типа. Размер определяется по типу операнд. [...]

  3. При применении к операнду, который имеет тип char, unsigned char или подписанный char, (или его квалифицированной версии), результат равен 1. [...]

Как вы можете видеть, поскольку тип символьной константы int, для sizeof('a') мы получаем sizeof(int), что равно 4 на вашей платформе. Однако для sizeof(c) мы получаем размер a char, который определяется как 1.

Итак, почему мы можем назначить 'a' a char?

§6.5.16.1:

  2. В простом присваивании (=) значение правильного операнда преобразуется в тип выражения присваивания и заменяет значение, хранящееся в объекте, обозначенном левым операндом.

Итак, int, то есть 'a', неявно преобразуется в char. Там также есть пример, явно показывающий, что int может быть неявно преобразован в char.

Ответ 2

Компилятор неявно преобразует int в char.

int i = 42;
char c = i * 2 - 4;

Эта последняя строка интерпретируется компилятором как:

char c = (char)(i * 2 - 4);

Эти неявные преобразования типов обрабатываются компилятором - там нет "переполнение буфера". (char) обрабатывается внутренне (самой машиной, скорее всего, для простых типов, таких как int). Он соответствующим образом сокращает лишние байты и сохраняет "подпись" (+/-).

Ответ 3

"Литерал символов имеет тип int" (http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7l.doc%2Flanguage%2Fref%2Fclrc02ccon.htm)

Но C позволяет делать теоретически "небезопасные" автоматические броски - это нормально, например,

char c = 34;

хотя 34 явно является 4-байтным int. Что делает это безопасным, так это то, что вы знаете, когда пишете 'a', что это действительно 1 символ ascii и, следовательно, 1 байт.

Хороший вопрос, кстати, немного смутил меня.