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


298

Який розмір символів у С та С ++? Наскільки я знаю, розмір char становить 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 ++?


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

Відповіді:


348

У 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 ++ значно зменшився за останні п’ять років.
David R Tribble

3
Ух, я використав вашу роботу, щоб написати це, і ось ви на ТАК. Такий маленький світ!

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

У мові С символи буквально не є charтипом. C розглядає буквений символ як ціле число. Отже, різниці між sizeof('a')і sizeof(1).

Отже, розмір символу буквалів дорівнює величині цілого числа в С.

У мові C ++ символом буквеним є тип char. Cppreference Сея:

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

Так, у символі С ++ літерал - це тип char. Отже, розмір буквеного символу в C ++ становить один байт.

Ало, у своїх програмах ви використовували неправильний специфікатор формату для sizeofоператора.

C11 §7.21.6.1 (P9):

Якщо специфікація конверсії недійсна, поведінку не визначено.275) Якщо будь-який аргумент не є правильним типом для відповідної специфікації перетворення, поведінка не визначена.

Отже, ви повинні використовувати %zuспецифікатор формату замість %d, інакше це не визначена поведінка в C.


%zuне підтримується на багатьох платформах, але краща портативність, використання (int)sizeof(char)та форматування%d
chqrlie

Значення буквених символів не обов'язково є відповідним кодом ASCII. Це залежить від джерел і наборів символів виконання та від того, charтип чи типово підписаний чи непідписаний.
chqrlie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.