Você está na página 1de 8

PonteirosSaindodePesadelos

Autor:C00L3R_<c00f3r[at]gmail[dot]com>
Data:02/04/2012
Introduo
PorquePonteiros?
Geralmente,omeioacadmicodumaexplicaodePonteirosdeixandotodosenrolados,ecomapenas
obsico.
Oquefazatodosdesviardocaminhodosponteiros,ospoucosqueusam,soaquelesquetmsido
autodidataoufizeramalgumcurso.
Bom,algunslivrostmexemplosbonsdePonteiros,comonolivroAnsiC,deK&R,entretanto,afalta
depopularidadedetaisdicas,tornatalassuntomeioobscuro
Perguntasfrenticas:
PorqueusarPonteiros?
Desempenhoemaiormanipulaodosdados.
Eseeunousar?
NadepuraodecdigosSTACK,bemcomplicadasecomparadacomHEAP.Notratamentode
dadosgigantes,poderteralgumasTrapsMalditas.
Outropontointeressante,umadasdiferenasde64bitspara32bits,tantoem64como32,tem32bitem
int,entretanto,Ponteirotem64bitem64bit,eem32bittem32bit.Reflita...
Oqueponteiro?
Nadamaisqueumareferncia,umtipodedadoquearmazenaumendereo.
Vamosumexemplobsico,paradepoisveralgocomplexo:
#include <stdio.h>
#include <string.h>

intmain()
{
// ponteiro com int
int*x,*y;

// fazemos o casting para ponteiro de int


x=(int*)256;
y=(int*)256;
// casting para int antes da adio
printf("%d \n",((int)x)+((int)y));

puts("digite um numero para adicao com y...");
scanf("%d",&x);
printf("%d \n",((int)x)+((int)y));

// ponteiro com strings...


char*word;

word="ola";
puts(word);
word="lol";
puts(word);
// 0[l] 1[o] 2[l] word[2] logo temos "l"
printf("char: %c \n",*(word+2));

return0;
}
Ponteiros,ponteirosparafuno...
Vamosentenderalgumasprticascomuns,edepoispartirparaexemplos:
inti>Intvarivel'i'
int*p>'P'ponteiroparaumint
inta[]>Matriz'a'deInt
intf()>'F'funocomvalorderetornodotipoint
int**p>'Pp'ponteiroparaumponteiroparaumint
int(*pa)[]>'Pa'ponteiroparaumarraydeint
int(*pf)()>pfponteiroparaumafunocomvalorderetornoint
int*p[]>Array'p'deponteirosparaumint
int*var()>Funo"var",queretornaumponteiroparaumint
int***var>'var'ponteiroparaumponteiroparaumponteiroparaumint
int(**var)[]>'var'ponteiroparaumponteiroparaumarraydeint
int(**var)()>'var'ponteiroparaumponteiroparaumafunocomvalorderetornodotipoint
int*(*c)[]>'c'ponteiroparaumamatrizdeponteirosparaumint
int*(*c)()>"c'ponteiroparaumafunocomvalorderetornodotipoponteiroparaumint
int**app[]>'App'ponteiroparaumponteiroparaumamatrizdeponteirosparaumint
int(*b[])[]>Umasriede'b'ponteirosparaumarraydeint
int(*c[])()>Umarray'c'ponteirosparaumafunocomvalorderetornodotipoint
int***fpp()>"Fpp'funoqueretornaumponteiroparaumponteiroparaumponteiroparaum
int
int(*fpa())[]>Funo'fpa",queretornaumponteiroparaumarraydeint
int(*fpf())()>"FPF"funoqueretornaumponteiroparaumafunocomvalorderetornoint
Fiquecalmo,noparadecorar.Tenhaemmente:leituradaesquerdaparadireita,esemprecomeando
pelonomedavarivel.
UmaprticamuitocomumemC,usarVoidPointer,paramuitosqueestoiniciandononormalde
sever,entretanto,estudandocdigosdeterceiros,podesevermuito.
UsarPonteirocolaboranodesempenhoeocdigoemAssemblygerado,ficamenordefato.Um
'DisassembleMain'noGDBpodetedarpontoemprico.
Umexemplovalemaisdoquemilpalavras:
// exemplo void pointer by Cooler_
#include <stdio.h>

//ideia de polimorfismo
voidfoo(void*point,intsize)
{
// int == 4 bytes
if(size==sizeof(int))
//tem que fazer casting do ponteiro para STDOUT
printf("int : %d , bytes: %d\n",*(int*)point,sizeof(point));

// double == 8 bytes
if(size==sizeof(double))
//casting de novo para o write(1...
printf("double : %f , bytes: %d\n",*(double
*)point,sizeof(double));
}

intmain()
{
inta=64;
doubleb=3.14;

printf("bytes do void : %d\n",sizeof(void));


// & usamos para dizer o endereo da memria de determinada
varivel
foo(&a,sizeof(int));
foo(&b,sizeof(double));

return0;
}
Outroexemplo,seguindoamesmalgica:
#include <stdio.h>
#include <string.h>

typedefstruct_myst
{
inta;
charb[10];
}myst;

voidfunc(myst *mt)
{
printf("resposta %d %s \n",mt->a,mt->b);
}

intmain()
{
void(*resposta)(void*);

myst x;
x.a=4;
strncpy(x.b,"1234",8);
resposta = (void*)func;
resposta(&x);

return0;
}
Outraprticamuitovista:Ponteirodearraysparafunes.
Vejamosumterceiroexemplo:
// example pointer of arrays to function by Cooler_
#include <stdio.h>
#include <malloc.h>

voidfoo1(intx)
{
printf("int: %d\n",x);
}

voidfoo2(intx)
{
printf("num: %d\n",x);
}

voidfoo3(intz)
{
printf("result %d\n",z*z);
}

voidfunc2func(void(*fp)(void*), void*q)
{
fp(q);
}

intmain()
{
//se a funo tiver mais de um argv use "," (int,char...
void(**list)(int);
//alocamos 3 endereos na heap
list=(void*)malloc(3*sizeof(void*));

list[0]=foo1;
list[0](2);
list[1]=foo2;
list[1](4);
list[2]=foo3;
list[2](8);

// funo para funo lol


func2func(foo2, 4);

free(list);
return0;
}
Ponteirosparafunocomargumentoearraystridimensionais
Outroexemplo,usandofunocomargumentoparafuno:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define w printf
#define MAX_BUF 128
#define array_num(array) (sizeof(array) / sizeof *(array))

voidbubble(void*p, intwidth, intN,int(*fptr)(constvoid*,
constvoid*));
intcompara_letras(constvoid*m, constvoid*n);
intcompara_numeros(constvoid*m, constvoid*n);

intmain()
{
intlista[]={4,2,1,5,3,8,10,9,0,45};
charnomes[6][20] =
{"Madruga","Arara","Zebra","Elefante","Babaca","Gato"};
shorti;

for(i=0; i<=array_num(lista)-1; i++)
w("%d\n",lista[i]);
for(i=0; i<=array_num(nomes)-1; i++)
w("%s\n",nomes[i]);
w("--------------\nagora dando buble sort nas listas\n");
bubble(lista, 4, 10, compara_numeros);
bubble(nomes, 20, 6, compara_letras);
for(i=0; i<=9; i++)
w("%d\n",lista[i]);
for(i=0; i<=5; i++)
w("%s\n",nomes[i]);

return0;
}

// funo com argumento para funo


voidbubble(void*p, intwidth, intN, int(*fptr)(constvoid*,
constvoid*))
{
inti, j, k;
unsigned charbuf[MAX_BUF];
unsigned char*bp = p;
for(i = N-1; i >= 0; i--)
{
for(j = 1; j <= i; j++)
{
//repare que fptr a funo escolhida pelo usurio
k = fptr((void*)(bp + width*(j-1)), (void*)(bp +
j*width));
if(k > 0)
{
memcpy(buf, bp + width*(j-1), width);
memcpy(bp + width*(j-1), bp + j*width , width);
memcpy(bp + j*width, buf, width);
}
}
}
}
//comparando letras graas "strcmp" funo da lib "string.h"
intcompara_letras(constvoid*m, constvoid*n)
{
char*m1 = (char*)m;
char*n1 = (char*)n;
return(strcmp(m1,n1));
}
//comparando numeros
intcompara_numeros(constvoid*m, constvoid*n)
{
long*m1, *n1;
m1 = (long*)m;
n1 = (long*)n;
return(*m1 > *n1);
}
Outroexemploarraystridimensionaiscomponteiros:
/*
* Explanao arrays tridimensionais com Ponteiros
*
*
*
* c00f3r[at]gmail[dot]com
* by Cooler_
*/
#include <stdio.h>
#include <stdlib.h>

intmain()
{
/* array tridimensional
*
* [][][]
* | | |_posio do caracter, todos caracter formam 1 palavra
* | |___nmero da posio onde esta a palavra
* |____ nmero da lista de palavras a usar
*

*/
// produto por 2 de char** pois vamos fazer 2 listas de
palavras
char***lists=(char***)malloc( 2*sizeof(char**) );

//produto por 3 em char* pq vamos usar 3 palavras


*(lists+0)=(char**)malloc(3*sizeof(char*));
// pode-se fazer tb lists[0][0]="ola"
*(*(lists+0)+0)="ola";
*(*(lists+0)+1)="Yay";
*(*(lists+0)+2)="lol";

*(lists+1)=(char**)malloc(3*sizeof(char*));
*(*(lists+1)+0)="epic";
*(*(lists+1)+1)="let";
*(*(lists+1)+2)="omg";

fprintf(stdout," %s \n %s \n %c\n",lists[0][2],lists[1]
[0],lists[0][0][1]);
/* mostrando uma saida qualquer
repare o terceiro elemento palavra "ola" segunda letra "l"

lists[0][0][1]='l'
|
[o][l][a] _|
0 1 2
*/

// usar free() onde usou malloc() para liberar memria HEAP


free(lists[0]);
free(lists[1]);
free(lists);

// caso use windows coloque um pause aqui no final ;-)


return0;
}
Temmuitasdicassobreomesmopora,masvoudarumasugestodeleituracasoqueiramelhorarainda
maisemPonteiros.
Ofamosolivrodatruta:
Vejaaversooriginaldomeupaper:
http://coolerlab.wordpress.comSaindodosPesadeloscomPonteiros
http://www.vivaolinux.com.br/artigo/PonteirosSaindodePesadelos
Voltarparaosite

Você também pode gostar