Curso de C
Conversão de Tipo
Você está em: MarMSX >> Cursos >> C
A conversão de tipo (em inglês typecasting) diz respeito a ação de adaptar um certo tipo de dado de origem para o tipo de dado de destino, tanto em associações de variáveis, como em expressões matemáticas.
Ela pode ser realizada de duas maneiras:
Implícita
A conversão de dados entre tipos distintos não é sinalizada no código. Dessa forma, ela é feita automaticamente pelo compilador. Ex:
#include <stdio.h>
int i;
double d;
void main(void)
{
i = 4;
d = i; // Conversão implicita: int para double
}
Explícita
A conversão de dados entre tipos distintos é sinalizada no código.
#include <stdio.h>
int i;
double d;
void main(void)
{
i = 4;
d = (double) i; // Conversão explicita: int para double
}
Conversão explicita com ponteiros
#include <stdio.h>
#include <stdlib.h>
int *i;
double d;
unsigned char *c;
void main(void)
{
i = (int *) malloc(sizeof(int));
*i = 4;
d = (double) *i; // Conversão entre estático e ponteiro
printf("%.2f\n", d);
*i = (int) d; // Conversão entre estático e ponteiro
printf("%d\n", *i);
c = (char *) i; // Conversão entre ponteiros
printf("%d\n", *c);
}
Saída:
4.00
4
4
O programa a seguir é equivalente ao programa exposto no capítulo de ponteiros do curso de Pascal, onde um ponteiro do tipo byte lia uma seqüência de caracteres de uma string.
#include <stdio.h>
unsigned char *p;
int i;
char nome[7] = "Poliana";
void main(void)
{
p = (unsigned char *) &nome;
for (i=0; i<7; i++)
{
printf("%04x - %02x - %c\n", p, *p, *p));
p++;
}
}
Saída:
0EFA - 50 - P
0EFB - 6F - o
0EFC - 6C - l
0EFD - 69 - i
0EFE - 61 - a
0EFF - 6E - n
0F00 - 61 - a
Cuidados na Conversão entre Tipos Numéricos
O C é uma linguagem traiçoeira quando se trata de números. Todo o cuidado é pouco para que o resultado final de uma equação não saia distante do esperado.
Quando colocamos um número sem casa decimal, estamos informando que este é um número do tipo inteiro. Quando colocamos um número com casa decimal, estamos informando que este é um número do tipo real.
Para entender melhor esse mecanismo, vejamos o programa a seguir.
#include <stdio.h>
int y;
main()
{
y = 2.8 + 2;
printf("O resultado é: %d\n",y);
}
Saída:
O resultado é: 4
O primeiro passo é resolver a expressão "2.8 + 2". Depois, o resultado é passado para a variável "y".
A simples presença do número real "2.8" irá transformar o resultado da expressão "2.8 + 2" em um número real. Nesse caso, há uma conversão implícita de "2" para "2.0".
Depois, o resultado da expressão "2.8 + 2", que é "4.8", deverá ser convertido para inteiro, uma vez que a variável y é do tipo "int". Nessa conversão, o número real "4.8" é truncado, resultando em "4".
Agora atente para esse exemplo:
#include <stdio.h>
float y;
main()
{
y = 2/5;
printf("O resultado é: %f\n",y);
}
Saída:
O resultado é: 0.000000
Como assim? Não deveria ser 0.4?
O compilador entende que "2/5" é uma expressão do tipo "int" e retorna "0" como resposta. Depois esse "0" inteiro é convertido para real.
Entretanto, se colocarmos pelo menos um dos números da expressão "2/5" como real, o problema será resolvido. Ex:
#include <stdio.h>
float y;
main()
{
y = 2.0/5;
printf("O resultado é: %f\n",y);
}
Saída:
O resultado é: 0.400000
Quando a variável da resposta for do tipo "float" e você estiver fazendo uma divisão, onde um dos termos é uma variável do tipo "int", coloque o outro termo com a casa decimal. Ex:
float y;
int z=4;
main()
{
y = z/5.0;
printf("O resultado é: %f\n",y);
}
Saída:
O resultado é: 0.800000
Outra solução é realizar o casting:
#include <stdio.h>
main()
{
int a=3, b=4;
float y;
y = (float) a/b;
printf("Valor de y: %.2f\n", y);
}
Saída:
Valor de y: 0.75
O procedimento mais seguro é converter explicitamente todas as variáveis de diferentes tipos contidos na expressão.
Obs: as seguintes funções da biblioteca "math.h" convertem de real para inteiro:
- round - arredonda para cima. Ex: round(4.8) = 5.
- trunc - ignora a casa decimal. Ex: trunc(4.8) = 4.
- ceil - caso ponto flutuante maior que 0, joga para cima. Ex: ceil(4.1) = 5.
- floor - Joga para baixo. Ex: floor(4.9) = 4.
Função de Formatação de Strings
Uma grande vantagem da classe "string" do C é a saída de texto formatada. Assim como formatamos a saída de texto pelo comando "printf", podemos gerar uma string formatada para uma variável do tipo string, através do comando "sprintf".
Sintaxe do sprintf:
sprintf(variavel_string_destino, "formatação", lista_variaveis);
Exemplo:
#include <stdio.h>
#include <string.h>
char str[10];
int a=45;
void main(void)
{
/* Formata a string e armazena em str */
sprintf(str, "O valor de 'a' em hexadecimal é %x", a);
/* Imprime a string str */
printf("%s\n", str);
}
Saída:
O valor de 'a' em hexadecimal é 2D
Subcadeias de Strings
Como realizar uma operação em C semelhante ao mid$(str, pos, tam) do Pascal?
Através da função "strncpy".
strncpy(str_nova, str+pos, tam);
Para obter apenas uma letra da string, faça:
letra = str[pos];
Onde pos varia de 0 a N-1.
Exemplo:
#include <stdio.h>
#include <string.h>
char letra;
char str[10] = "MSX", str_nova[3];
void main(void)
{
letra = str[0];
printf("A primeira letra de %s é: %c\n", str, letra);
strncpy(str_nova, str+1, 2);
printf("As duas últimas letras de %s são: %s\n", str, str_nova);
}
Saída:
A primeira letra de MSX é: M
As duas últimas letras de MSX são: SX
Convertendo de String para Inteiro ou Double
As seguintes funções da biblioteca "stdlib.h" convertem de string para números:
- atof - Converte de string para real.
- atoi - Converte de string pata inteiro.
- atol - Converte string para longo.
Exemplo:
#include <stdio.h>
#include <stdlib.h>
char str[] = "15.87";
double d;
void main(void)
{
d = atof(str);
printf("Valor convertido para double: %.2f\n", d);
}
Saída:
Valor convertido para double: 15.87
Obs: para converter de número para string, utilize o "sprintf".