int составляет 4 байта, но все же он может быть сохранен в char, почему нет переполнения - PullRequest
13 голосов
/ 19 июня 2011

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

#include<stdio.h>

int main (){

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

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

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

Ответы [ 3 ]

15 голосов
/ 19 июня 2011

Сначала согласно ANSI / IEC 9899: 1999 (E) §6.4.4.4:

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

§6.5.3.4:

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

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

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

Так почему мы можем присвоить 'a' char?

§6.5.16.1:

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

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

2 голосов
/ 19 июня 2011

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

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

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

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

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

1 голос
/ 19 июня 2011

"Символьный литерал имеет тип 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. Что делает это безопасным, так это то, что вы знаете, когда пишете «а», что это действительно 1 символ ascii и, следовательно, 1 байт.

Кстати, хороший вопрос - немного смутил меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...