Introdução aos caracteres

Nesta seção examinaremos resumidamente como utilizar caracteres tanto em C quanto em Python. Desse modo, quem está aprendendo uma das linguagens poderá aprender o funcionamento equivalente na outra.

Representação como caractere

Como citado na seção sobre variáveis, a informação básica nos computadores digitais é uma sequência de bits e o contexto é quem indica como estes bits devem ser interpretados. Por exemplo, a sequência com 6 bits 100001, poderia ser interpretada como um valor inteiro e neste caso seria o valor 33, pois 1*2^5 + 0*2^4 + 0*2^3 + 0*2^3 + 0*2^2 + 0*2^1 + 1*2^0 = 32+1 = 33. Por outro lado, a mesma sequência poderia ser interpretada como um caractere, no caso o '!' (exclamação).

Assim as linguagens de programação possibilita a interpretação de uma sequência de bits como um caractere (e.g. como uma letra ou um dígito). Deste modo para apresentá-lo é preciso estabelecer uma tabela de conversão, por exemplo, que indique que a sequência 110000 deve ser interpretada como o caracteres '0', que corresponde ao decimal 1*2^5 + 1*2^4 + 0*2^3 + 0*2^3 + 0*2^2 + 0*2^1 + 0*2^0 = 32+16 = 48.

Código ASCII

Um primeiro padrão para representar os caracteres é o American Standard Code for Information Interchange. O padrão ASCII é bastante antigo, ainda da década de 1960 e por isso utiliza um número reduzido de bits, somente 8, o que possibilita a codificação de apenas 28=256 símbolos distintos.

Tab. 1. Os 20 primeiros números naturais na base binária (0, 1) e correspondente decimal
Binário Decimal
00000000 0
00000001 1
00000010 2
00000011 3
00000100 4
00000101 5
00000110 6
00000111 7
00001000 8
00001001 9
Binário Decimal
00001010 10
00001011 11
00001100 12
00001101 13
00001110 14
00001111 15
00010000 16
00010001 17
00010010 18
00010011 19

Como o padrão ASCII foi criado nos Estados Unidos e a lingua Inglesa não utiliza símbolos especiais, na pratica eles utilizavam apenas 7 bits, ou seja, usavam 128 diferentes caracteres.

Como exemplos de código ASCII a letra 'A' é associada ao natural 65, o 'B' ao 66 e assim por diante. Do mesmo modo, o 'a' é associada ao natural 97 e o caractere 'z' ao 122. Já o natural 48 é associado do dígito '0', o 49 ao '1' e assim por diante até o 57 associado '9'.

Entrada e saída de caracteres em C e em Python

Como já citado nas outras seções, o contexto deve definir como sequências de bits devem ser tratadas. Para tratar um conjunto bits como caractere deve-se indicar isso ao computador de alguma forma. Por exemplo, as linguagens de programação geralmente dispõem de um tipo de variável especial para caracteres.

Na linguagem C existe o tipo char e tanto para leitura quanto para impressão, utiliza-se o formatador %c. Mas pode-se imprimir uma variável char como se fosse um número inteiro e vice-versa, neste caso usa-se seu código ASCII.

Já em Python 2 é preciso de uma função especial para leitura de caracteres, a função raw_input(). Na impressão, se não for usada impressões especiais, não é preciso qualquer diferenciação, pois o Python aplica um filtro para tratar se a variávem sendo impressa é inteira, flutuante ou caractere. Vide tabela abaixo.

Tab. 2. Sobre a leitura de caracteres em C e em Python
C Python 2 Python 3
char x; // declaracao de variavel para armazenar caracteres
scanf("%c", &x); // leia como "caractere"
printf("%c", x); // imprima como "caractere"
# Vale notar: se o usuario digitar uma "string", como
# "nome", a variavel x recebera' a "string" toda
x = raw_intput(); # leia como "caractere"
print(x);

# Vale notar: se o usuario digitar uma "string", como
# "nome", a variavel x recebera' a "string" toda
x = intput(); # leia como "caractere"
print(x);

Constantes do tipo caractere em C e em Python

Assim como várias outras linguagens, C e Python, adotam o uso de apóstrofes para indicar que deve pegar o caractere entre os apóstrofes. Por exemplo, para atribuir a constante 'a' à uma variável do tipo caractere, de nome varc, deve-se usar

varc = 'a'; (o finalizador ';' é opcional em Python).

A necessidade de um marcador pode ser facilmente entendida ao escrevermos o código varc = a;, que corresponde a guardar o valor atual da variável a na variável varc.

Abaixo um exemplo de código que imprime primeiro o caractere associado ao código ASCII dado e depois o contrário. Ao rodar este código será impresso os caracteres de código 48, 49, 97, 98, 65 e 66, respectivamente '0', '1', 'a', 'b', 'A' e 'B'.

Tab. 3. Sobre conversão entre o caractere ASCII e seu código inteiro
C Python 2
#include <stdio.h>
int main (void) {
  int          // Criando 6 variaveis como (implicitamente) do tipo "int".
    val1 = 48, // Cada variavel recebera um valor inteiro que depois sera'
    val2 = 49, // interpretado como caractere.
    num1 = 97, //
    num2 = 98, //
    Num1 = 65, //
    Num2 = 66; //
  char            // Declarando variaveis tipo caractere
    charN1 = '0', // NOTE que para constantes do tipo
    charN2 = '1', // caractere, deve-se usar aspa simples
    Char1  = 'A', //
    Char2  = 'B', //
    char1  = 'a', //
    char2  = 'b'; //
  printf(" int | codigo\n"); // '\n' usado para forcar quebra de linha na impressao
  printf("  %d | %c\n", val1, val1);
  printf("  %d | %c\n", val2, val2);
  printf("  %d | %c\n", num1, num1);
  printf("  %d | %c\n", num2, num2);
  printf("  %d | %c\n", Num1, Num1);
  printf("  %d | %c\n", Num2, Num2);
  printf(" int | codigo\n");
  printf(" %c | %d\n", charN1, charN1);
  printf(" %c | %d\n", charN2, charN2);
  printf(" %c | %d\n", char1,  char1);
  printf(" %c | %d\n", char2,  char2);
  printf(" %c | %d\n", Char1,  Char1);
  printf(" %c | %d\n", Char2,  Char2);
  return 0;
  }
def main():
  val1 = 48 # Criando 6 variaveis como (implicitamente) do tipo "int".
  val2 = 49 # Cada variavel recebera um valor inteiro que depois sera'
  num1 = 97 # interpretado como caractere.
  num2 = 98 #
  Num1 = 65 #
  Num2 = 66 #
  print(" int | codigo")
  print(" ", val1, " | ", chr(val1)) # A funcao chr(...) devolve
  print(" ", val2, " | ", chr(val2)) # o caractere associado ao
  print(" ", num1, " | ", chr(num1)) # codigo ASCII dado
  print(" ", num2, " | ", chr(num2))
  print(" ", Num1, " | ", chr(Num1))
  print(" ", Num2, " | ", chr(Num2))
  charN1 = '0' # NOTE que para constantes do tipo
  charN2 = '1' # caractere, deve-se usar aspa simples
  Char1 = 'A' #
  Char2 = 'B' #
  char1 = 'a' #
  char2 = 'b' #
  print(" int | codigo")
  print("  ", charN1, " | ", ord(charN1)) # A funcao ord(...) devolve
  print("  ", charN2, " | ", ord(charN2)) # o codigo ASCII do caractere dado
  print("  ", char1, " | ", ord(char1))
  print("  ", char2, " | ", ord(char2))
  print("  ", Char1, " | ", ord(Char1))
  print("  ", Char2, " | ", ord(Char2))
main()

Como gerar uma tabelas ASCII em C e em Python

Vale destacar que a codificação dos caracteres segue uma organização lógica, uma vez que o código para o caractere 0 é o 48, então o 49 é para o 1 e assim por diante. Do mesmo modo, sendo 65 o código do caractere A, 66 é o caractere B e assim por diante.

Assim, podemos fazer um código para gerar tabelas dos caracteres e seu código ASCII, como ilustrado abaixo. Experimente alterar os limites do controle do laço, mas cuidado com os caracteres especiais, alguns podem "quebrar" linhas ou corresponder a outros caracteres de controle que podom deixar a tela "suja".

Em C a converção entre inteiro ou caractere é praticamente direta, bastando usar o formatador correto (%d para inteiro ou %c para caractere). Entretanto em Python é necessário usar duas funções pré-definidas para isso, ord(inteiro) e chr(caractere): sendo i inteiro, chr(i) fornece o caractere cujo código é i; sendo c caractere, ord(c) fornece o código do caractere c.

Tab. 4. Como imprimir uma tabela código ASCII e o correspondente caractere
C Python 2
#include <stdio.h>
int main (void) {
  int i, ini = 48, fim = 58;
  printf("cod. : car.\n");
  for (i=ini; i<fim; i++)
    printf(" %3d :  %3c\n", i, i);
  printf("------------\n");
  ini = 65; fim = 91;
  for (i=ini; i<fim; i++)
    printf(" %3d :  %3c\n", i, i);
  printf("------------\n");
  ini = 97; fim = 123;
  for (i=ini; i<fim; i++)
    printf(" %3d :  %3c\n", i, i);
  printf("------------\n");   
  return 0;
  }
def main () :
  ini = 48; fim = 58;
  print("cod. : car.\n");
  for i in range(ini, fim) :
    print(" %3d :  %3c" % (i, chr(i)));
  print("------------\n");
  ini = 65; fim = 91;
  for i in range(ini, fim) :
    print(" %3d :  %3c" % (i, chr(i)));
  print("------------");
  ini = 97; fim = 123;
  for i in range(ini, fim) :
    print(" %3d :  %3c" % (i, chr(i)));
  print("------------");
     
main();

Primeiro notem que usamos os formatadores %3d e %3c para ajustar 3 colunas à direita, o que é bastante útil para imprimir tabelas. O %d é utilizado para imprimir inteiro, enquanto %c para caractere, tanto em C, quanto em Python. Logo após a cadeia de caracteres, com eventuais valores a serem substituidos, deve vir uma lista de variáveis/valores compatíveis. No exemplo, a cadeia era formada por " %3d : %3c", portanto deveria vir a seguir 2 valores, o primeiro inteiro e o segundo caractere.

Entretanto existe uma diferença na sintaxe das duas linguagens, em C a lista de parâmetros vem separadas por vírgula simples, mas em Python precisa do símbolo de percentagem (%) após a cadeia de caracteres (" %3d : %3c") e, havendo mais de um valor a substituir, deve-se usar a sintaxe de lista ((i, chr(i))).

Note que o Python precisa de uma função especial para conveter inteiro em caractere, chr(i), que devolve o caractere cujo código seja o valor armazenado na variável i (que deve ser inteira). Para fazer o oposto deve-se usar a função ord(varc) que é a função que devolve o código ASCII (ordenado) do caractere armazenado na variável varc (que neste caso deve ser para caractere - char).

Leônidas de Oliveira Brandão
http://line.ime.usp.br

Alterações:
2020/08/19: novo formato, pequenas correções
2019/04/18: acerto '0010'=4 para '100001'=33, explicita funções ord e chr)
2018/04/28: acertos no texto (valor 2^8) e cortada a parte sobre numero em ponto flutuante
2017/05/01: primeira versão