Caracteres são um dos tipos-de-dados básicos da linguagem C. Há dois tipos de caracteres em C: sem sinal (= unsigned characters) e com sinal (= signed characters). Um caractere-sem-sinal nada mais é que um número natural entre 0 e 255, enquanto um caractere-com-sinal é que um número inteiro entre -128 e 127. A distinção entre os dois tipos é, em geral, irrelevante. [Os padrões de bits dos dois tipos são os mesmos: 00000000 a 11111111.] Cada caractere (de qualquer dos dois tipos) é armazenado em um byte na memória do computador. Para criar uma variável u do primeiro tipo, diga
unsigned char u;
Para criar uma variável c do segundo tipo, diga
char c;
Quando um caractere é exibido na impressora ou na tela do monitor de vídeo, ele é representado por um símbolo gráfico. No intervalo 0..127, os dois tipos de caracteres têm os mesmos símbolos gráficos. O símbolo do caractere 65, por exemplo, é
A
e o símbolo do caractere 66 é B. Alguns caracteres têm símbolos gráficos estranhos. Assim, por exemplo, o caractere 32 é representado por um espaço, o caractere 0 tem representação vazia (não ocupa espaço algum), e o caractere 10 é representado por uma mudança de linha.
Os símbolos gráficos e os efeitos não gráficos dos caracteres 0 a 127 foram estabelecidos pelo American Standard Code for Information Interchange. A correspondência é conhecida como "tabela ASCII". Os símbolos dos caracteres-sem-sinal 128 a 255 e os símbolos dos caracteres-com-sinal -128 a -1 não estão bem padronizados: cada sistema escolhe a tabela que mais lhe agrada. Uma das tabelas mais difundidas é a ISO 8859-1 (também conhecida como ISO Latin1). Eis uma amostra dessa tabela:
| símbolo gráfico | unsigned char | unsign char | constante C |
| caractere nulo | 0 | 0 | '\0' |
| mudança de linha | 10 | 10 | '\n' |
| quebra de página | 12 | 12 | '\f' |
| espaço | 32 | 32 | ' ' |
| ' | 39 | 39 | '\'' |
| * | 42 | 42 | '*' |
| + | 43 | 43 | '+' |
| - | 45 | 45 | '-' |
| / | 47 | 47 | '/' |
| 0 | 48 | 48 | '0' |
| 1 | 49 | 49 | '1' |
| 2 | 50 | 50 | '2' |
| ; | 59 | 59 | ';' |
| A | 65 | 65 | 'A' |
| N | 78 | 78 | 'N' |
| O | 79 | 79 | 'O' |
| a | 97 | 97 | 'a' |
| o | 111 | 111 | 'o' |
| ã | 227 | -29 | 'ã' |
| ç | 231 | -25 | 'ç' |
| ÿ | 255 | -1 | 'ÿ' |
A última coluna dá a representação dos caracteres como constantes do tipo char.
Cada caractere-com-sinal c no intervalo -128..-1 tem o mesmo símbolo gráfico que o caractere-sem-sinal c+256. A tabela abaixo mostra a correspondência: os caracteres que estão em uma mesma coluna da tabela têm o mesmo símbolo gráfico.
| char | 0 | 1 | . . . | 127 | -128 | -127 | -126 | . . . | -2 | -1 |
| unsigned char | 0 | 1 | . . . | 127 | 128 | 129 | 130 | . . . | 254 | 255 |
Do ponto de vista prático, a única diferença entre os dois tipos de caracteres é a seguinte: quando os caracteres-com-sinal são colocados em ordem crescente, as letras acentuadas (como á) precedem as não acentuadas (como a), enquanto o contrário acontece com os caracteres-sem-sinal.
Não é cômodo escrever as constantes do tipo char como "97", "-29", "57", etc:
char c, d, e; c = 97; d = -29; e = 57;
É muito melhor escrever o símbolo gráfico do caractere embrulhado em aspas simples:
c = 'a'; d = 'ã'; e = '9';
Para os caracteres "especiais", que têm símbolos incomuns, as constantes começam com um "\". Por exemplo, '\n' é o mesmo que 10 (a letra n é a inicial de newline) e '\0' é o mesmo que 0.
Os caracteres 9, 10, 11, 12, 13 e 32 (ou seja, '\t', '\n', '\v', '\f' '\r' e ' ') são conhecidos como brancos (= white-spaces). Muitas funções C tratam todos os brancos como se fossem ' '. É o caso, por exemplo, da função scanf.
O tipo-de-dados char pode ser automaticamente convertido em int e vice-versa. (O mesmo vale para unsigned char e int.) Seguem alguns exemplos. Em todos, x tanto pode ser uma variável do tipo char quanto uma do tipo int.
CHAR=A INT=65
CHAR=0 INT=48
CHAR= INT=0
CHAR= INT=10
CHAR=ã INT=-29
As operações aritméticas envolvendo variáveis do tipo char e unsigned char são executadas em aritmética int (todos os operandos são previamente convertidos ao tipo int) e não módulo 256, como alguém podeira imaginar. Assim, por exemplo, se as variáveis u e v são do tipo unsigned char e valem 255 e 2 respectivamente, o valor da expressão u+v é 257.
Já as atribuições de um inteiro a um caractere são feitas módulo 256. Assim, por exemplo, se u é uma variável do tipo unsigned char e c é uma variável do tipo char então depois de
u = 256; c = 130;o valor de u será 0 e o valor de c será −126 (pois −126 é o único inteiro k no intervalo −128..127 tal que a diferença 130−k é um múltiplo inteiro de 256). Por isso, os processos iterativos abaixo "entram em loop":
unsigned char u; for (u = 0; u < 256; ++u) printf( ".");
char c; for (c = 0; c < 128; ++c) printf( ".");
Já os seguintes fragmentos de código imprimem todas as letras minúsculas, como seria de se esperar:
char c; for (c = 'a'; c <= 'z'; c += 1) printf( "%c\n", c);
int i; for (i = 1; i < 26; ++i) printf( "%c\n", 'a' + i - 1);