Ferramentas do usuário

Ferramentas do site


tipos_dados

Tipos Básicos

Para se criar variáveis em um programa C deve-se indicar para o compilador qual o tipo desta variável. Uma variável pode ter um tipo básico, intrínseco à linguagem C ou tipo estruturado, montado pelo programador. O programador pode criar novos tipos de dados, utilizando a declaração typedef.

A linguagem C define os seguintes tipos básicos de variáveis:

  • int - Variável tipo inteira. Deve ser utilizado para se armazenar valor inteiro, com ou sem sinal.
  • char - Variável do tipo caracteres. Servirá para se armazenar um único caractere.
  • float - Para valores com casas decimais (reais) deve-se utilizar este tipo. Ele pode armazenar números reais com até 6 dígitos significativos.
  • double - É o mesmo que o anterior, só que pode armazenar mais dígitos, dando uma precisão maior nos cálculos com casas decimais.

O tipo void deve ser utilizado não para variáveis, mas sim para indicar que uma função não tem nenhum valor retornado ou não possui nenhum parâmetro de entrada.

A padronização Ansi C 99 especifica ainda mais 2 tipos de variáveis:

  • _Bool - Variável tipo booleana (verdadeiro ou falso). Ressalta-se que na linguagem C, em comparações lógicas, 0 (zero) é considerado falso e diferente de 0 (zero) é considerado verdadeiro
  • complex - Variável para trabalhar com valores complexos (raízes imaginárias, por exemplo).

Abrangência e Modificadores de Tipo

A linguagem ANSI C determina para cada tipo intrínseco um certo tamanho em bytes. Este tamanho irá determinar a escala de valores que pode ser colocada dentro de um determinado tipo.

Abaixo estão os limites de valores aceitos por cada tipo e o seu tamanho ocupado na memória. Também nesta tabela está especificado o formato que deve ser utilizado para ler/imprimir os tipos de dados com a função scanf e printf

Tipo Número de bits Formato para leitura/impressão Início Fim
_Bool 8 Não tem (pode-se utilizar %d) 0 1
char 8 %c -128 127
unsigned char 8 %c 0 255
signed char 8 %c -128 127
int 32 %i -2.147.483.648 2.147.483.647
unsigned int 32 %u 0 4.294.967.295
signed int 32 %i -2.147.483.648 2.147.483.647
short int 16 %hi -32.768 32.767
unsigned short int 16 %hu 0 65.535
signed short int 16 %hi -32.768 32.767
long int 32 %li -2.147.483.648 2.147.483.647
signed long int 32 %li -2.147.483.648 2.147.483.647
unsigned long int 32 %lu 0 4.294.967.295
float 32 %f 3,4E-38 3.4E+38
double 64 %lf 1,7E-308 1,7E+308
long double 80 %Lf 3,4E-4932 3,4E+4932

Estes limites podem ser verificados no arquivo limits.h do pacote C e são válidos para plataformas de 32 bits. Em platarmos de 16 bits, o int era definido com 16 bits (o equivalente a short int na plataforma de 32 bits). Em plataformas de 64 bits:

Tipo Número de bits Formato para leitura/impressão Início Fim
long 64 %li -9223372036854775806 9223372036854775807
unsigned long 64 %lu 0 18446744073709551615

O tamanho de uma varíavel ou de um tipo pode ser verificado com o operador sizeof.

Pode-se modificar o comportamento de um tipo básico, tanto no tamanho (espaço em memória) como no seu sinal (positivo ou negativo). Os modificadores de sinais indicam para o compilador considerar ou não valores negativos para o tipo inteiro. Apesar de existir a palavra signed ela é padrão não precisando ser colocada, mas pode sofrer influência do sistema operacional.

A palavra unsigned indica para o compilador não considerar o bit de sinal, estendendo assim o limite da variável inteira.

Pode-se modificar o tamanho das variáveis do tipo int para que ele ocupe somente dois bytes na memória, reduzindo assim o limite de abrangência para –32768 a +32767. Para isto coloca-se o modificador short na definição da variável, indicando que será utilizado somente dois bytes de tamanho. Devem-se tomar alguns cuidados com a portabilidade, pois num sistema a variável pode ser considerada signed e em outros unsigned, em alguns sistemas operacionais (variações de Unix, OS/2 da IBM, etc.) as variáveis são definas por padrão com unsigned (sem sinal), em outros como signed (com sinal).

Conversão de Tipos

De uma forma geral pode-se realizar a conversão de um tipo para outro da linguagem C utilizando o que se chama de typecast. Esta técnica é muito utilizada para se melhorar o entendimento de alguns trechos de programas. Outras vezes utiliza-se o typecast para compatibilizar um determinado tipo de um parâmetro na chamada de uma função para o tipo do parâmetro esperado por aquela função.

A sintaxe do typecasting é: (tipo) valor_constante (tipo) variável

No primeiro formato o compilador irá realizar a transformação da constante indicada para o tipo indicado entre parênteses durante o processo de compilação. No segundo formato o compilador irá gerar o código adequado para que a conversão ocorra em tempo de execução.

Exemplos:

int iASCII = (int) ‘E’; /* Código ASCII do ‘E’ */
 
 
/* converter o resultado de uma divisão para inteiro */
short int si;
float f;
int i;
i = (int) (f/si);

Formatadores de Tipos

Para cada variável colocada no comando printf ou correlatos deve-se indicar qual o formato desejado de saída. Isto é feito colocando-se o caractere ‘%’ seguido de uma letra dentro do texto informado como primeiro parâmetro da função printf.

As funções não fazem nenhuma verificação entre o tipo real da variável e o caractere formatador indicado. Também não é feita à verificação do número correto de formatadores, um para cada variável. Quando isto acontecer, só será percebido quando da execução do programa, gerando resultados imprevisíveis.

Formato Tipo da Variável Conversão realizada
%c caracteres char, short int, int, long int
%d inteiros int, short int, long int
%e Ponto flutuante, notação científica float, double
%f Ponto flutuante, notação decimal float, double
%lf Ponto flutuante; notação decimal double
%g O mais curto de %e ou %f float, double
%o Saída em octal int, short int, long int, char
%s String char *, char []
%u Inteiro sem sinal unsigned int, unsigned short int, unsigned long int
%x Saída em hexadecimal (0 a f) int, short int, long int, char
%X Saída em hexadecimal (0 a F) int, short int, long int, char
%ld Saída em decimal longo Usado quando long int e int possuem tamanhos diferentes

Indicando o Tamanho

Quando é feita a saída do valor de uma variável, além de se especificar o tipo (formato) que deve ser mostrado, pode-se indicar o tamanho da saída.

A indicação do tamanho depende do tipo da variável. Para os números inteiros (int, short int, long int, unsigned int, unsigned short int e unsigned long int) a especificação do tamanho tem a seguinte sintaxe:

% [tamanho].[qtd_dígitos]d

Onde:

  • tamamanho - Indica o tamanho mínimo que deve ser colocado na saída caso o número possua quantidade menor de dígitos. Se o número possuir quantidade de dígitos maior que o valor, o número não será truncado.
  • qtd_dígitos - Quantidade de dígitos que deve ser mostrada. Caso o número possua quantidade menor que o indicado, serão colocados zeros à esquerda até se completar o tamanho indicado.

Para os números reais (float e double), têm-se o seguinte formato:

% [tamanho].[casas_decimais]f

Onde:

  • tamamanho - É o mesmo que descrito acima para os números inteiros. Vale completar que neste tamanho estão consideradas as casas decimais inclusive.
  • casas_decimais - Número de casas decimais que devem ser mostradas. Caso o número possua número menor de decimais, o número será completado com zeros até o tamanho indicado. Se o número possuir um número de casas decimais maior que o indica a saída será truncada para o tamanho indicado.

Para as variáveis do tipo string pode-se indicar o tamanho mínimo e máximo a ser mostrado através da seguinte sintaxe:

%[tamanho].[tamanho_máximo]s

Neste caso se a string possuir tamanho menor que o indicado a saída será completada com brancos à esquerda.

Veja o exemplo da função printf.

Outros tipos

O sistema operacional pode definir alguns tipos e de dados também, estas definições podem ser encontradas no arquivos sys/types.h do seu compilador.

Alguns exemplos:

  • pid_t para número de PID (veja a função fork);
  • pthread_t para números de thread (veja as threads POSIX;
  • ssize_t para definir tamanhos de blocos (vejas as funções para tratamento de rede)

Estas definições são utilizadas para garantir a portabilidade entre as plataformas 32 e 64 bits.

Marcos Laureano 2009/02/14 12:36

tipos_dados.txt · Última modificação: 2023/09/12 16:14 por 127.0.0.1