Conversão de Tipos em C - Básico

Started by Dark_Side, 17 de October , 2006, 01:35:15 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Dark_Side

Introdução

Hi,

Em C, para declaramos uma variável, devemos especificar seu nome e o tipo cujo o qual esta pertence. Muitas vezes, uma variável de um determinado tipo, possui um valor que em uma função por exemplo, só pode ser aceito se o tipo de variável for outro. Pode-se então, converter esse valor para o tipo requerido.

O objetivo deste tutorial é justamente abordar a conversão de tipos de dados, isto é, explicar como converter tipos de variáveis em outros, apresentando uma solução para essa situação descrita.


Tipos de variáveis

Temos 5 tipos básicos de variáveis em C, são eles:
 
Obs:: Valores baseados em uma plataforma de 32 bits

QuoteInt (em 32 bits, o tipo Long possui a mesma especificação)

   Inteiro; ocupa 4 bytes; utilizado para armazenar números inteiros tanto
negativos quanto positivos. Exemplos: -2,-51,-100,53,0,1,23,45...


Char
   
   Caractere; ocupa 1 byte; utilizado para armazenar caracteres.
   Exemplos: 'a','b','c','X','Y','Z'...

Float
   
   Números reais (ponto flutuante com precisão simples); Ocupa 4 bytes;
   Exemplos: 1.5,2.4,-10.5,20.55...
   
Double
   
   Números reais (ponto flutuante com precisão dupla); Ocupa 8 bytes.
   Exemplos: 2.3,-23.53,535.53,1234.56...

Void

   Vazio; pode ser transformado em qualquer um dos tipos listados acima.

 

Conversão de tipos

Vejamos:

 int x = 100;

Acima declaramos uma variável denominada "x" do tipo inteiro, inicializada com o valor 100, isto é, x = 100.
Supondo que temos a seguinte estrutura:

int x = 100;
char ch;

Como faríamos para atribuir à varíavel "ch" o valor de "x" ?

Podemos simplesmente fazer:

int x = 100;
char ch = x;

Pois bem, o valor de "ch" agora é 100.

Para confirmar, observe o programa abaixo:

#include <stdio.h> /* para usar printf() */
int main()
{
int x = 100;
char ch;
ch = x;
printf("X = %d\nCH = %c",x,ch);

return 0;
}

Resultado do programa:

X = 100
ch = d

Pois bem, utilizamos os formatadores "%d" e "%c" para mostrar na tela os valores do inteiro e do char, respectivamente. Mas por que o valor de "ch" foi mostrado como "d"? Como já foi dito, variáveis do tipo char armazenam caracteres. Cada caractere possui um código númerico que o identifica - Código Ascii.
 
O código Ascii do caractere  "d" é 100, isso explica o valor impresso pela função.

Por essa mesma razão, podemos fazer:

char ch = 'A';
int x = ch;

O código ASCII de 'A' é 65, portanto, o valor de "x" passaria a ser 65.


Quando atribuímos um valor de um inteiro a um caractere diretamente ou vice-versa, temos uma conversão implícita, onde o compilador converte os valores automaticamente.

Segue abaixo as possíveis conversões implícitas:

Quoteint para char;
int para float;
int para double;

char para int;
char para float;
char para double;

float para int;
float para char;
float para double;

double para int;
double para char;
double para float;

Poderíamos dizer que é possível converter valores numéricos implicitamente.

Vejamos:
#include <stdio.h> /* para usar printf() */
int main()
{
int x = 65; /* Valor inicial => inteiro */
char a = x; /* inteiro para char */
float b = a; /* char para float */
double c = b; /* float para double */

printf("X = %d\n",x);
printf("A = %c\n",a);
printf("B = %f\n",b);
printf("C = %Lf\n",c);


return 0;
}

Resultado do programa:

X = 65
A = A
B = 65.000000
C = 65.000000

Existe ainda a conversão explícita denominada TYPE CASTING, que consiste em forçar que um tipo de dado seja interpretado como outro, veja:

int x = 100;
char y = (char)x;

Da mesma forma, o valor de y seria 100 (caractere "d"), porém, convertemos explicitamente os valores.

QuoteSintaxe:
 
var1 = (tipo)var2;
 
  var1:
     nome da variável que receberá o valor;
 
  tipo:
     tipo => converter em;

  var2:
     variável a ser convertida.

Outro exemplo:

char ch = 'X';
int n = (int)ch;

O código ASCII do caractere 'X' é 88, portanto, na conversão, o valor de
"n" seria 88.

Existe um tipo de conversão que não pode ser realizado utilizando os métodos acima, vejamos:

---------------------------------
/* Incorreto! */

char string[6] = "12345";
int numero = string;

ou


/* Incorreto! */

char string[6] = "12345";
int numero = (int)string;

---------------------------------

Quando tentamos converter uma string para um inteiro, como no caso acima, o resultado é o endereço para o primeiro elemento (caractere) da string.

Lolz??? vamos por parte:

Uma string é um array, também chamado vetor, que armazena caracteres cujo o último é o caractere NULO ('\0').

Exemplo:

char string[6]="ABCDE";

Temos 6 possíveis valores para o vetor que variam de 0 a 5 (o primeiro índice de um array em C é 0).


Caractere: A B C D E \0
Posição:     0 1 2 3 4 5 -> último índice
                   
Cada elemento é armazenando em um endereço de memória, e quando fazemos: "x = string" estamos atribuindo à variável X o endereço de memória referente  ao primeiro elemento da string, que no caso, é o caractere 'A'.

Então, como convertemos um valor de uma string para um inteiro e vice-versa?

Não só para inteiros, podemos utilizar funções auxiliares, definidas em
"stdlib.h". São elas:

QuoteFunção          | Descrição
----------------------------------------------------------------------------------------
atoi()        =>    Conversão de string para inteiro;
atol()        =>   Conversão de string para inteiro longo;
atof()        =>   Conversão de string para ponto flutuante (double ou float);

itoa()        =>   Conversão de inteiro para string;
ltoa()        =>    Conversão de inteiro longo para string;
gcvt()        =>   Conversão de ponto flutante(double ou float) para string;
----------------------------------------------------------------------------------------

Função atoi()

QuoteSintaxe:
 
int atoi(const char* string);
 
  string:
       string a ser convertida.

A função retorna o valor convertido.

Exemplo:

#include <stdio.h> /* para usar printf() */
#include <stdlib.h> /* conversões */
int main()
{
char string[10]="12345";
int n;

n = atoi(string);
printf("n = %d",n);

return 0;
}

Resultado do programa:
n = 12345

--------------------------------------------

Função atol()

QuoteSintaxe:
 
long atol(const char* string);
 
  string:
       string a ser convertida.


A função retorna o valor convertido.


Exemplo:

#include <stdio.h> /* para usar printf() */
#include <stdlib.h> /* conversões */
int main()
{
char string[10]="9485234";
long n;

n = atol(string);
printf("n = %ld",n);

return 0;
}

Resultado do programa:
n = 9485234

--------------------------------------------

Função atof()

QuoteSintaxe:
 
double atof(const char* string);
 
  string:
       string a ser convertida.


A função retorna o valor convertido.

Exemplo:
#include <stdio.h> /* para usar printf() */
#include <stdlib.h> /* conversões */
int main()
{
char string[10]="100.5";
float n;

n = atof(string);
printf("n = %f",n);

return 0;
}

Resultado do programa:
n = 100.500000

--------------------------------------------

Função itoa()
QuoteSintaxe:
 
char * itoa(int numero,char * buffer, int base);
 
  num:
       número a ser convertido;

  buffer:
       buffer que receberá o valor;

  base:
       base numérica para a qual o número será convertido:
         
             2  - binária
             8  - octal
             10 - decimal
             16 - hexadecimal

A função retorna o valor convertido.

Exemplo:
#include <stdio.h> /* para usar printf() */
#include <stdlib.h> /* conversões */
int main()
{
char valor[10];
int num=1234;
itoa(num,valor,10); /* Converte 1234 para string, na base decimal */

printf("valor = %s",valor); /* Mostra o valor na tela - "%s" => utilizado para imprimir strings */
return 0;
}

Resultado do programa:
valor = 1234

--------------------------------------------

Função ltoa()

QuoteSintaxe:
 
char * itoa(long numero,char * buffer, int base);
 
  num:
       número a ser convertido.

  buffer:
       buffer que receberá o valor;

  base:
       base numérica para a qual o número será convertido:
         
             2  - binária
             8  - octal
             10 - decimal
             16 - hexadecimal

A função retorna o valor convertido.

Exemplo:

#include <stdio.h> /* para usar printf() */
#include <stdlib.h> /* conversões */
int main()
{
char valor[10];
long num=1234;
ltoa(num,valor,16); /* Converte 1234 para string, na base HEXADECIMAL */

printf("valor = %s",valor);
return 0;
}

Resultado do programa:
valor = 4D2

--------------------------------------------

Função gcvt()

QuoteSintaxe:
 
char * gcvt(double numero,int digitos, char * buffer);
 
  num:
       número a ser convertido;

  digitos:
       número de digitos que serão escritos na string (incluindo o separador: ".");
         

  buffer:
       buffer que receberá o valor.


A função retorna o valor convertido.

Exemplo:
#include <stdio.h> /* para usar printf() */
#include <stdlib.h> /* conversões */
int main()
{
char valor[10];
double num = 10.50;
gcvt(num,4,valor); /* Imprime 4 dígitos */
printf("valor = %s",valor);

return 0;
}


Resultado do programa:
valor = 10.5


Quando o número de digitos especificado, for menor do que o número total de dígitos do número em ponto flutuante, o valor é arredondado, exemplo:

#include <stdio.h> /* para usar printf() */
#include <stdlib.h> /* conversões */
int main()
{
char valor[10];
float num = 100.70;
gcvt(num,3,valor);  /* O valor NUM possui 6 dígitos, porém apenas 3 serão impressos => arredonda 100.70 para 101 */
printf("valor = %s",valor);

return 0;
}

Resultado:
valor = 101



Finalizando

Termino aqui este breve tutorial sobre conversão de tipos em C.
Embora existam outras funções utilizadas para a conversão de tipos, as listadas acima são as principais. As demais funções, são utilizadas para converter valores de variáveis que tenham seu tipo modificado. Um exemplo de variável com tipo modificado é "unsigned long"
onde há uma especificação para que esta variável armazene apenas números positivos.

É isso...
Bye.

whit3_sh4rk

Fiquei perdido por não saber C, mas cara, parabéns!

Ótimo tutorial! Bem explicado e completo.. Quem entende de C, dêem suas opiniões aí..

Continue assim cara!

[]s

insanity

he he, realmente esse tuturial foi bem explicado, apesar de eu saber isso, vou ler para revisar ;)


// insanity

Anonymous

#3
itoa nao e do padrao C ansi, no linux nao iria encontrar essa funcao por exemplo.
otimo texto



a funcao bem simples aqui pra converter int pra string
http://www.freebookzone.com/others/itoa.h

nizep

otimo tuto Dark_Side

mas tenho uma duvida

e qnd vc quizer transformar apenas um valor da strig??

eh que to fazendu um verificador de cpf e pra isso preciso de cada n. separadu

tipo

n1 = string[1]
n2 = string[2]
e assim por diante

eu tava tentando assim

n1 = atoi (string[1]);
n2 = atoi (string[2];
..........

mas da um erro:
conversao invalida - char para const *char


se alguem ae puder ajudar vlws

Dark_Side

Hi,

No seu caso, essa conversão pode ser feita sem o uso de funções auxiliares.

Como você provalmente já sabe, string é uma estrutura básica de dados composta por uma seqüência de caracteres. Estes caracteres possuem um valor numérico  único e exclusivo que serve como identificação: o código ASCII.

Uma vez em que uma string é um array de caracteres, você pode acessar cada elemento de forma separado da forma como você mesmo fez:

string[1], string[2], etc.

Exemplo:

string = "ABC";

string[0] = A;
string[1] = B;
string[2] = C;

Algo importante: os índices do array, nas linguagens C/C++, sempre começam por ZERO.

Indo um pouco além, podemos verificar que os códigos ASCII's para os caracteres A, B e C, são, respectivamente: 65, 66 e 67.

Como se pode observar, são valores numéricos. Isso significa que você pode fazer uma conversão direta:

int x = string[0];

Da forma acima, o valor ASCII (numérico) do primeiro caractere da string (o caractere A = 65 ASCII) seria atribuído como valor da variável "valor".

Outro exemplo:

string = "12345";

Vejamos:

string[0] = 1;
string[1] = 2;
string[2] = 3;
string[3] = 4;
string[4] = 5;

Se fizermos:

int a = string[0];
int b = string[1];

Os valores de "a" e "b", seriam, respectivamente, os códigos ASCII dos caracteres '1' e '2'.

Lembre-se que uma string é uma seqüência de caracteres, por isso o valor de cada elemento é seu código ASCII. Portanto, os valores das variáveis seriam 49 (caractere 1) e 50 (caractere 2).

Os números de 0 a 9, em ASCII, variam da seguinte forma:

Quote48 - 0
49 - 1
50 - 2
51 - 3
52 - 4
53 - 5
54 - 6
55 - 7
56 - 8
57 - 9

Se você observar bem, verá que estes valores seguem um padrão. Uma vez em que os valores são progressivos, você pode efetuar uma simples operação com uma constante para retornar um caractere como um inteiro.

Se subtrairmos os códigos ASCII por 48 - código ASCII do caractere 0 -, temos:

Quote48 - 48 = 0
49 - 48 = 1
50 - 48 = 2
51 - 48 = 3
52 - 48 = 4
53 - 48 = 5
54 - 48 = 6
55 - 48 = 7
56 - 48 = 8
57 - 48 = 9

Nota-se que obtivemos os valores inteiros para os respectivos códigos ASCII.

Podemos agora converter cada elemento da string para seu valor inteiro:

#include <stdio.h>

int main()
{
char digitos[]="12345";

int a,b,c,d,e;

a = digitos[0] - '0';
b = digitos[1] - '0';
c = digitos[2] - '0';
d = digitos[3] - '0';
e = digitos[4] - '0';

printf("%d\n",a);
printf("%d\n",b);
printf("%d\n",c);
printf("%d\n",d);
printf("%d\n",e);

return 0;
}

No exemplo acima convertemos os valores ASCII de cada caractere da string para seu respectivo valor inteiro e, em seguida, armazenamos os valores inteiros obtidos em cada variável.

Talvez você se pergunte por que foi utilizado  - '0' no código acima. A resposta é simples: como vimos anteriormente, subtraindo cada código ASCII pelo valor constante 48, podemos obter os números correspondentes a tais valores diretamente. A verdade é que tanto faz usar '0' ou 48, uma vez em que '0' é um caractere cujo valor ASCII é 48.

Assim, o código acima poderia também ser escrito assim:

#include <stdio.h>

int main()
{
char digitos[]="12345";

int a,b,c,d,e;

a = digitos[0] - 48;
b = digitos[1] - 48;
c = digitos[2] - 48;
d = digitos[3] - 48;
e = digitos[4] - 48;

printf("%d\n",a);
printf("%d\n",b);
printf("%d\n",c);
printf("%d\n",d);
printf("%d\n",e);

return 0;
}


Você se deparou com um erro ao usar a função atoi() devido ao fato de que esta requer uma string como argumento (const char*) e, ao passar "string[1]" (char) como valor, o compilador detecta a incompatibilidade de tipos e lhe retorna tal erro.

Acho que é isso.
Qualquer coisa é só postar xD
Bye.

Anonymous

nizep po hauahuah, me deparei com esse mesmo problema quando estava aprendendo C, e eu estava fazendo justamente isso que vc está fazendo do cpf(e cpnj tbm) e talz... bom te passar minha funçao que fiz pra isso naqueles tempos...

char sotoi(char vac)
{
int in[10] = {48,49,50,51,52,53,54,55,56,57};
int ch[10] = {0,1,2,3,4,5,6,7,8,9};
int reti;
int seq = 0;
for(seq = 0;seq <= 9;seq++){
if(vac == in[seq]){
reti = ch[seq];
}
}
return reti;
}

Ve aí se funfa... se não conseguir usar ou tiver problemas na construção do verificador de cpf go to #uazine irc.freenode.org  ou posta aqui mesmo que alguem ajuda... é que eu quase não venho aqui entao...

Anonymous

Ps: apesar de funcionar mude alí para int...

char sotoi(char vac)
para
int sotoi(char vac)

Ps: sotoi pq sonic atoi, hauhauahua

nizep

@ Dark_Side

valew mrm velho eu nunca ia imaginar que tinha ANCII no meio...

tava a dois dias tentando faze issu funfa... fiz de mil formas diferentes mas sempre o mrm erro...

agora vai rola de acaba o programa  :D

qnd tive pronto eu boto o code ae

@ Sonics

vlw por posta a funçao mas na verdade eu ja tenho ela pronta so que em pseudocodigo

fiz essa funçao no curso de logica e tava tentando faze em C agora mas aparece essa pedra nu caminho...

a noite vo faze o prog e vo da uma olhada ae na tua funçao ke agora to di saida

vlws