====== Tipos Básicos ======
Para se [[variavel_definicao|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 [[entrada_saida|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|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.eti.br|Marcos Laureano]] 2009/02/14 12:36//