Размер символа ('a') в C / C ++

299

Каков размер символов в C и C ++? Насколько я знаю, размер символа составляет 1 байт в C и C ++.

В С:

#include <stdio.h>
int main()
{
    printf("Size of char : %d\n", sizeof(char));
    return 0;
}

В C ++:

#include <iostream>
int main()
{
    std::cout << "Size of char : " << sizeof(char) << "\n";
    return 0;
}

Не удивительно, они оба дают вывод: Size of char : 1

Теперь мы знаем , что персонажи представлены в виде 'a', 'b', 'c', '|', ... Так что я просто изменил вышеуказанные коды к этим:

В С:

#include <stdio.h>
int main()
{
    char a = 'a';
    printf("Size of char : %d\n", sizeof(a));
    printf("Size of char : %d\n", sizeof('a'));
    return 0;
}

Вывод:

Size of char : 1
Size of char : 4

В C ++:

#include <iostream>
int main()
{
    char a = 'a';
    std::cout << "Size of char : " << sizeof(a) << "\n";
    std::cout << "Size of char : " << sizeof('a') << "\n";
    return 0;
}

Вывод:

Size of char : 1
Size of char : 1

Почему sizeof('a')возвращает разные значения в C и C ++?

whacko__Cracko
источник
8
"%|"Формат требует intаргумента (или что - то , что способствует int). sizeofдает результат типа size_t. Либо преобразуйте в intиспользование приведения, либо, если ваша реализация это поддерживает, используйте "%zu".
Кит Томпсон,

Ответы:

349

В C тип символьной константы, такой как 'a'фактически int, имеет размер 4 (или другое значение, зависящее от реализации). В C ++ тип имеет charразмер 1. Это одно из многих небольших различий между двумя языками.

Эрик Постпищил
источник
12
В стандарте C ++ это раздел 2.13.2 / 1, в C 6.4.4.4, по крайней мере, в моей документации.
14
+1 (за исключением того, что, хотя «размер 4», очевидно, относится к платформе nthrgeek, это не обязательно относится ко всем платформам.)
sbi
28
@nthrgeek: Мне лень цитировать оба стандарта, но в стандарте C ++ есть приложение, посвященное несовместимости с C. В Приложении C.1.1 упоминается, что «Тип буквенного символа изменен с intна char, что объясняет поведение. :)
jalf
3
@nthrgeek: §6.4.4.4, абзац 10: «Целочисленная символьная константа имеет тип int. Значением целочисленной символьной константы, содержащей один символ, который отображается на однобайтовый исполнительный символ, является числовое значение представления сопоставленного символа. символ интерпретируется как целое число. "
Стивен Кэнон
7
@nthrgeek: Вы не должны запрашивать стандартную ссылку, если у вас нет аргумента о конкретной точке, и вы не хотите понять, почему у другого человека другое мнение. Если все согласны, просто примите это. Вы (как разработчик) должны быть достаточно умны, чтобы быстро найти общий ответ, подобный этому, самостоятельно.
Мартин Йорк
26

Как сказал Пол, это потому, что 'a'он intв C, а charв C ++.

Я освещаю эту конкретную разницу между C и C ++ в том, что написал несколько лет назад по адресу: http://david.tribble.com/text/cdiffs.htm.

Дэвид Р. Триббл
источник
4
Просто любопытно, но вы работаете над обновлением этого (очень подробного) документа, чтобы включить новые изменения в C ++ 11 и C11?
Адам Розенфилд
Не сейчас. Мой интерес к C и C ++ сильно уменьшился за последние пять лет или около того.
Дэвид Р. Триббл
3
Я использовал твою работу, чтобы написать это, и вот ты здесь на SO. Такой маленький мир!
17

В C тип символьных литералов int и char в C ++. Это в C ++ требуется для поддержки перегрузки функций . Смотрите этот пример:

void foo(char c)
{
    puts("char");
}
void foo(int i)
{
    puts("int");
}
int main()
{
    foo('i');
    return 0;
}

Вывод:

char
кузнец
источник
5

В языке C символьный литерал не является charтипом. C рассматривает символьный литерал как целое число. Таким образом, нет разницы между sizeof('a')и sizeof(1).

Таким образом, размер буквенного символа равен размеру целого числа в C.

В языке C ++ символьный литерал является типом char. Cppreference Сэя:

1) узкий символьный литерал или обычный символьный литерал, например, 'a'или '\n'или '\13'. Такой литерал имеет типchar и значение, равное представлению c-char в наборе символов выполнения. Если c-char не может быть представлен как один байт в наборе символов выполнения, литерал имеет тип int и значение, определяемое реализацией.

Итак, в C ++ символьный литерал является типом char. Итак, размер символьного литерала в C ++ составляет один байт.

Alos, в ваших программах вы использовали неверный спецификатор формата для sizeofоператора.

C11 §7.21.6.1 (P9):

Если спецификация преобразования недопустима, поведение не определено.275) Если какой-либо аргумент не является правильным типом для соответствующей спецификации преобразования, поведение не определено.

Таким образом, вы должны использовать %zuспецификатор формата вместо %d, иначе это неопределенное поведение в C.

ЦКМ
источник
%zuне поддерживается на многих платформах, но лучшая переносимость, использование (int)sizeof(char)и форматирование%d
chqrlie
Значение символьных литералов не обязательно соответствует соответствующему ASCII-коду. Это зависит от исходного и исполнительного наборов символов и от того, charявляется ли тип подписанным или неподписанным по умолчанию.
chqrlie