Tamanho do caractere ('a') em C / C ++

298

Qual é o tamanho do caractere em C e C ++? Tanto quanto eu sei, o tamanho do caractere é de 1 byte em C e C ++.

Em C:

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

Em C ++:

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

Sem surpresas, os dois fornecem a saída: Size of char : 1

Agora sabemos que os caracteres são representados como 'a', 'b', 'c', '|', ... Então, eu só modificou os códigos acima para estes:

Em 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;
}

Resultado:

Size of char : 1
Size of char : 4

Em 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;
}

Resultado:

Size of char : 1
Size of char : 1

Por que os sizeof('a')valores diferentes retornam em C e C ++?

whacko__Cracko
fonte
8
O "%|"formato requer um intargumento (ou algo que promova int). sizeofproduz um resultado de tipo size_t. Converta para intusar uma conversão ou, se sua implementação suportar, use "%zu".
91111 Keith Thompson

Respostas:

348

Em C, o tipo de constante de caractere como 'a'na verdade é um int, com tamanho de 4 (ou algum outro valor dependente da implementação). Em C ++, o tipo é char, com tamanho de 1. Essa é uma das muitas pequenas diferenças entre os dois idiomas.

Eric Postpischil
fonte
12
No padrão C ++, é a seção 2.13.2 / 1, no C 6.4.4.4, pelo menos no documento que tenho.
14
+1 (exceto que, embora o "tamanho de 4" obviamente se aplique à plataforma da nthrgeek, ele não se aplica necessariamente a todas as plataformas).)
sbi
28
@ nthrgeek: Estou com preguiça de citar os dois padrões, mas o padrão C ++ possui um apêndice dedicado a incompatibilidades com C. No Apêndice C.1.1, ele menciona que "O tipo de caractere literal foi alterado de intpara char, o que explica o comportamento. :)
jalf
3
@nthrgeek: §6.4.4.4, parágrafo 10: "Uma constante de caractere inteiro possui o tipo int. O valor de uma constante de caractere inteiro contendo um único caractere que mapeia para um caractere de execução de byte único é o valor numérico da representação do mapeado caractere interpretado como um número inteiro ".
Stephen Canon
7
@ nthrgeek: você não deve pedir uma referência padrão, a menos que esteja discutindo um ponto específico e queira entender por que a outra pessoa tem uma opinião diferente. Se todos concordarem, apenas aceitem. Você (como desenvolvedor) deve ser bastante inteligente o suficiente para encontrar rapidamente respostas comuns como essa sozinho.
Martin York
26

Como Paul afirmou, é porque 'a'é um intem C, mas um charem C ++.

Cubro essa diferença específica entre C e C ++ em algo que escrevi há alguns anos, em: http://david.tribble.com/text/cdiffs.htm

David R Tribble
fonte
4
Apenas curioso, mas você está trabalhando para atualizar esse documento (muito detalhado) para incluir as novas alterações no C ++ 11 e C11?
Adam Rosenfield
Não no momento. Meu interesse em C e C ++ diminuiu bastante nos últimos cinco anos.
precisa
3
Eu usei seu trabalho para escrever isso e aqui está você. Um mundo tão pequeno!
17

Em C, o tipo de literal de caracteres é int e char em C ++. Isso é necessário em C ++ para dar suporte à sobrecarga de funções . Veja este exemplo:

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

Resultado:

char
Smith
fonte
5

Na linguagem C , o caractere literal não é um chartipo. C considera o caractere literal como inteiro. Portanto, não há diferença entre sizeof('a')e sizeof(1).

Portanto, o tamanho literal do caractere é igual ao tamanho inteiro em C.

Na linguagem C ++ , o caractere literal é o tipo de char. A cppreference diz:

1) literal de caracteres estreitos ou literal de caracteres comuns, por exemplo, 'a'ou '\n'ou '\13'. Esse literal tem tipochar e valor igual à representação de c-char no conjunto de caracteres de execução. Se c-char não for representável como um byte único no conjunto de caracteres de execução, o literal terá o tipo int e o valor definido pela implementação.

Portanto, no caracter C ++, literal é um tipo de char. portanto, o tamanho do caractere literal em C ++ é de um byte.

Além disso, em seus programas, você utilizou um especificador de formato errado para o sizeofoperador.

C11 §7.21.6.1 (P9):

Se uma especificação de conversão for inválida, o comportamento será indefinido.275) Se algum argumento não for do tipo correto para a especificação de conversão correspondente, o comportamento será indefinido.

Portanto, você deve usar o %zuespecificador de formato em vez de %d, caso contrário, é um comportamento indefinido em C.

msc
fonte
%zunão é suportada em muitas plataformas, mas melhor portabilidade, a utilização (int)sizeof(char)eo formato%d
chqrlie
O valor dos caracteres literais não é necessariamente o código ASCII correspondente. Depende dos conjuntos de caracteres de origem e execução e se o chartipo é assinado ou não por padrão.
chqrlie