Professional Documents
Culture Documents
Introduo Aritmtica com ponteiros Ponteiros e argumentos de funes Ponteiros e vetores Vetores de ponteiros Equivalncia entre ponteiros e vetores Ponteiros para funes Referncias (alguns comentrios sobre)
Os ponteiros so variveis que guardam endereos de memria char vc=5; Por exemplo: char *p,**pp;
p=&vc; pp=&p;
vc 100 5 Normal
Introduo 01/15
Correspondncia para variveis que contenham endereo na memria onde objetos de um tipo qualquer residam Um ponteiro aponta para algum lugar ou objetos na memria
MEMRIA **pp vc *p 5 100 1001
Passagem de parmetros por referncia Passagem de parmetros (vetores e matrizes) Manipulao de matrizes Alocao dinmica Estruturas de dados (e.g. listas encadeadas, rvores binrias,...) Etc.
Introduo 03/15
Situaes inconvenientes:
Problemas imprevisveis E.g. um ponteiro pode apontar para um lugar invlido Ponteiros que oscilam
Introduo 04/15
Redobrar a ateno!
Introduo 05/15
Alocao:
Normalmente ocupam uma palavra de mquina
O tamanho dos registradores (i.e. da palavra) indica a quantidade de dados com a qual o computador pode trabalhar em um momento
Alocao:
Espao somente para o prprio ponteiro nenhum espao alocado para os dados de referncia. O compilador atribui cada varivel a uma nica localizao de memria
Formas de armazenzamento:
Declarao de uma varivel para o ponteiro Sintaxe:
<tipo> *<nome_da_variavel>;
float *p;
Alocao dinmica
(tipo *) malloc(sizeof(tipo))
Introduo 08/15
Vazamento de memria:
Blocos de armazenagem alocados e no liberados, mesmo eu no estejam mais em uso
Soluo:
Gerenciamento do armazenamento:
Inicializao de estruturas de dados Destruio de estruturas de dados (i.e. liberao de memria)
Declarao:
* (no endereo)
int i, *pi, **ppi;
Os operadores * e & tm maior precedncia do que todos os operadores aritmticos, exceto o menos unrio
Introduo 10/15
Endereos de memria
i pi ppi
90 9F
90 9F 100
pi ppi
Introduo 11/15
Endereos de memria
pi ppi
NULL 9F
i pi ppi
90 9F 100
Endereos de memria
i pi ppi
E neste caso?
90 NULL
90 9F 100
pi ppi
Introduo 13/15
j=i; i=2;
Introduo 14/15
#include<Stdio.h> das variveis declaradas? main() { int i=5,j=0; int x, *px, **ppx; int *p; char*p; int a; float vetor[10]; px=&x; ppx=&px; p=&i; j=*p; *p=2; printf(Tam. Vetor: %d\t Tam. Ponteiro p: %d\t Tam. a: %d, sizeof(vetor), sizeof(*p), sizeof(a) ); }
Introduo 15/15
Dados agregados:
Dados compostos de elementos mltiplos agrupado
Estruturas Tipo registro Vetores/Matizes
Aritmtica:
Associao de cada ponteiro com um tipo base determinado feita atravs do tipo base do ponteiro Operaes:
Adio Subtrao
Considere:
pf = ponteiro de float vet = vetor de float
#include <Stdio.h> main() { float *pf; float vet[20]; pf = vet; pf++; pf = pf + 2; pf--; vet++; }
O que acontecer?
Cada vez que um ponteiro incrementado, ele passa a apontar para a posio de memria do *pi; prximo elemento do seu tipo base. int pi++; Cada vez que decrementado, ele aponta para a pi--; posio do elemento anterior. Observao:
Ponteiros para variveis do tipo caractere segue as regras supracitadas
No possvel multiplicar ou dividir ponteiros No possvel usar os operadores de deslocamento e de mascaramento bit a bit com ponteiros No possvel adicionar ou subtrair o tipo float ou double a ponteiros
...
Modularizao:
Por valor Por referncia
Programa principal Sequncia de cdigo repetido
...
// Prottipo das funes int funcao1([parmetros]); // Programa principal main() { ... funcao1([parmetros]); ... }
Reestruturao
Uso
Programa principal
<Nome>(Parmetros);
// Corpo da funo declarada anteriormente int funcao1([parmetros]) { ... // Corpo (i.e. bloco de instrues) ... return [valor(es)]; }
...
...
...
<Nome>(Parmetros);
<Nome>(Parmetros);
<Nome>(Parmetros);
...
...
...
...
Mdulos (i.e. procedimentos e funes) podem ou no receber dados de quem (i.e. funo cliente) os invoca Conceito:
So dados recebidos pelo mdulo que foram passados no ato de sua chamada
Requisitos:
Devem possuir o mesmo tipo dos parmetros enviados pela parte do cdigo que chamou o mdulo
Ponteiros e argumentos de funes 02/20
Procedimentos:
PROC <Nome>([Parmetros]) { Bloco de instrues Retorne; }
Funes:
Tipo FUNC <Nome>([Parmetros]) { Bloco de instrues Retorno <valor>; }
Parmetros: ...<Nome> (tipo <nome da varivel>, tipo <nome da varivel>, ...) { ... }
Tipos de manipulao:
Por valor:
Cpia do contedo
Por referncia:
Endereo da varivel Operadores: &, *
Por valor:
Cpia do contedo
Funo Cliente() { ... p = 5; Mdulo(p); ... } Mdulo(p) { ... retorno [<valores>]; }
p 5 p 5
Ponteiros e argumentos de funes 05/20
Por valor:
Cpia do contedo
Funo Cliente() { ... p = 5; Mdulo(p); ... }
O que acontecer?
Mdulo(p) Ponteiro de { fluxo de ... execuo p = 7; retorno [<valores>]; }
p 5 p 5
Ponteiros e argumentos de funes 06/20
Por valor:
Cpia do contedo
Funo Cliente() { ... p = 5; Mdulo(p); ... } Mdulo(p) { ... p = 7; retorno [<valores>]; }
p 5 p 7
Ponteiros e argumentos de funes 07/20
Por referncia:
Endereo da varivel
Funo Cliente() { ... Endereo de p p = 5; Mdulo(&p); ... } Mdulo(*p) { ... retorno [<valores>]; }
Endereo de p (&p)
5 *p
Por referncia:
Endereo da varivel
Funo Cliente() { ... Endereo de p p = 5; Mdulo(&p); ... }
O que acontecer?
Mdulo(*p) Ponteiro de { fluxo de ... execuo p = 7; retorno [<valores>]; }
Endereo de p (&p)
5 *p
Por referncia:
Endereo da varivel
Funo Cliente() { ... Endereo de p p = 5; Mdulo(&p); ... } Mdulo(*p) { ... p = 7; retorno [<valores>]; }
Endereo de p (&p)
7 *p
Em Linguagem C:
// Passagem de Parametro #include "stdio.h" #include "stdlib.h" void trocanao(float, float); void trocasim(float *, float *); void trocatalvez(float &, float &); int main(int argc, char* argv[]) { float x=7.0, y=13.0; printf("x= %f\ty= %f\n", x, y); trocanao(x, y); printf("x= %f\ty= %f\n", x, y); trocasim(&x, &y); printf("x= %f\ty= %f\n", x, y); trocatalvez(x, y); printf("x= %f\ty= %f\n", x, y); system("pause"); return 0; }
void trocanao(float copia_1_de_x, float copia_1_de_y) { float auxiliar; auxiliar = copia_1_de_x; copia_1_de_x = copia_1_de_y; copia_1_de_y = auxiliar; printf("Funcao trocanao x= %f\ty= %f\n",copia_1_de_x , copia_1_de_y); return; } void trocasim(float *copia_2_de_x, float *copia_2_de_y) { float auxiliar; auxiliar = *copia_2_de_x; *copia_2_de_x = *copia_2_de_y; *copia_2_de_y = auxiliar; printf("Funcao trocasim x= %f\ty= %f\n",*copia_2_de_x , *copia_2_de_y); return; } void trocatalvez(float &a, float &b) { float auxiliar; auxiliar = a; a = b; b = auxiliar; printf("Funcao trocatalvez x= %f\ty= %f\n", a, b); return; }
#include "stdio.h" #include "stdlib.h" Lista* funcao01(Lista *, int); void funcao02(Lista **, int); main() { Lista *pLista; pLista = NULL; pLista = funcao01(pLista, 7); funcao02(&pLista, 13); system("pause"); return 0; }
Lista* funcao01(Lista *p, int info) { Lista *pAux; pAux = p; return pAux; }
void funcao02(Lista **pp, int info) { Lista *pAux; // Realizam-se as operaes em pAux *pp = pAux; return; }
Por referncia:
Vantagens:
Temos o controle total sobre a passagem de parmetros
Desvantagens:
Lentido do controle devido ao cancelamento da referncia dos parmetros todas as vezes quantas forem necessrias em uma funo
Por referncia:
Passagem de vetores para funes (ponteiros no modificveis)
int funcao01(int vet[10]) { vet[0] = 7; return 0; } int funcao02(int *vet) { *vet = 7; return 0; }
So equivalentes?
Por referncia:
Informaes sobre limites so importantes quando tratamos com vetores multidimensionais ou matrizes
int funcao03(int vet[][3]) { vet[3][1] = 13; return 0; }
Todas as dimenses devem ser especificadas, exceto a primeira Possibilita a aritmtica com ponteiros
Funo de mapeamento:
Matriz bi-dimensional Por linhas: caso particular de ordem lexicogrfica mais comum
Endereco ( y [i, j ]) = E0 + ( ( i 1) n + j 1) tamanho (TipoDado )
Funo de mapeamento:
Matriz n-dimensional
Endereco ( z [in , in 1 ,..., i2 , i1 ]) = E0 + + ( ih 1) d m tamanho (TipoDado )
h =1 m =1 n h 1
onde
d
m =1
h 1
= d1 d 2 ... d h 1 ;
d
m =1
=1
Representao grfica
0 0 1 2
2 bytes
1 2 3
13
13
[0][0] [0][1] [0][2] [1][0] [1][1] [1][2] [2][0] [2][1] [2][2] [3][0] [3][1] [3][2]
Um ponteiro para um vetor do tipo char (segundo argumento). cada elemento do vetor uma cadeia de caracteres
#include <stdio.h> #include <stdlib.h> int main(int qtarg, char *arg[]) { int i; for(i=0; i<qtarg; i++) printf(%s\n,arg[i]); system(pause); return; }
De que local executamos o programa? Qual o primeiro elemento de vetor de ponteiros? E os demais?
Forte relao Seqncia contguo de elementos homogneos Linguagem C converte o vetor em um ponteiro no modificvel que aponta para o primeiro elemento do vetor
int i[10], *pi; pi = i; pi[0] = 7; int i[10], *pi; pi = i; *pi = 7;
So equivalentes?
Loudon (2000) Ponteiros e vetores 01/07
Vetores:
char cadeia[30], *pc; pc = cadeia; pc = &cadeia[0];
cadeia[13]
*(cadeia+13)
*(pc+13)
So equivalentes?
*(*(vet+i)+j)
vet[i][j]
As funes em Linguagem C so normalmente escritas com ponteiros Schildt (1997) Ponteiros e vetores 03/07
#include <stdio.h> #include <stdlib.h> main() { static char vetor[]=Eu adoro o C\0; char *pc; pc=&vetor[0]; while(*pc) printf(%c,*pc++); system(pause); return; }
u ...
d
*pc++
\0
pc=&vetor[0];
main() { int *pi, x=3, y; pi = &x; printf(Ponteiro:%d Pos.Mem.:%x\n, *pi, pi); y = *pi+1; pi = &y; printf(Ponteiro:%d Pos.Mem.:%x\n, *pi, pi); *pi++; printf(Ponteiro:%d Pos.Mem.:%x\n, *pi, pi); system(pause); return; }
x=3 pi=&x;
y=*pi+1;
1000
1001
1002
1003
3 ...
pi=&y;
Contedo do vetor:
Ponteiros de memria
Considere:
char *tab[5];
Isso quer dizer que o vetor *tab[5] pode guardar 5 ponteiros de memria
main() { static char *tab[]={Eu,Tu,Ele,Ns,Vs,\0}; int i; for(i=0; i<5; i++) printf(Nome: %s\n, tab[i]); system(pause); return; }
Problema:
Fazer um algoritmo que, baseado no programa anterior, ordene os dados do vetor.
Dica: Utilizar as funes da biblioteca string.h: strcmp() e strcpy().
Vetor unidimensional:
d[i]*(d+i) int i,*p,*q,z[10]; p=z+0; q=z+9; q=p+4; i=q-p; /* /* /* /* /* declaraes */ p aponta p/ z[0] */ q aponta p/ z[9] */ q aponta p/ z[4] */ i a diferena=4 */
Vetor n-dimensional:
z[i][j] *(z[i]+j) *(*(z+i)+j) float apf[4]; // ou *(apf[4]) int (*pai)[4] Ponteiro para um vetor de 4 int
A chamada funo realizada em linguagem de mquina Se existe um ponteiro que aponta para esse ponto de entrada da funo, ele pode ser usado para chamar essa funo
Schildt (1997) Ponteiros para funes 02/08
Sua obteno realizada atravs do nome da funo sem os parnteses e/ou parmetros
#include <stdio.h> #include <stdlib.h> main() { int(*funo)(); funo=printf; (*funo)(Ahrrr! Testando!\n); system(pause); return; }
void check(char *a, char *b, int (*cmp)(const char *, const char *)); void main(void) { char s1[80], s2[80]; int (*p)(); p = strcmp; gets(s1); gets(s2); check(s1, s2, p); } void check(char *a, char *b, int (*cmp)(const char *, const char *)) { printf("testando igualdade\n"); if(!(*cmp)(a, b)) printf("igual"); else printf("diferente"); }
Parnteses ao redor do *p ou do *cmp so necessrios para que o compilador interprete o comando corretamente
(*cmp)(a, b)
void check(char *a, char *b, int (*cmp)(const char *, const char *))
Pode trazer confuso Vantagens em passar funes arbitrrias a mdulos ou em manter uma vetor de funes, e.g.:
switch vs. ponteiros para funes
obrigatria a igualdade dos tipos (i.e. do ponteiro e do retorno da funo) Para obter o endereo de uma funo, basta digitar o seu nome sem os parnteses e/ou parmetros usar uma forma semelhante para declarar outros ponteiros para funes, embora o tipo de retorno possa ser diferente.
Schildt (1997, p. 127) Ponteiros para funes 07/08
#include <stdio.h> #include <string.h> void funcao_1(void); void funcao_2(void); void funcao_3(void); void funcao_4(void); void main() { void (*vetor_fun[4])(); int opcao; vetor_fun[0] = funcao_1; vetor_fun[1] = funcao_2; vetor_fun[2] = funcao_3; vetor_fun[3] = funcao_4; printf("\033[2J"); // Limpa a tela printf("Escolha opcao [0,1,2,3]: "); scanf("%d", &opcao); (*vetor_fun[opcao])(); system(pause); return; }
na funcao_2\n");
na funcao_3\n");
na funcao_4\n");
ASCENCIO, A. F. G. & CAMPOS, E. A. V. Fundamentos da programao de computadores Algoritmos, Pascal, C/C++. Pearson Prentice-Hall, 2005 FERRER, H. et al. Algoritmos Estruturados. 3 edio, Rio de Janeiro: LTC, 1999 SHILDT, H. C Completo e Total. So Paulo: Editora Makron Books, 1997 STALLINGS, W. Arquitetura e Organizao de Computadores. 5 edio, Prentice-Hall, 2005 TANENBAUM, A. Organizao Estruturada de Computadores. Rio de Janeiro: LTC, 2001
Referncias 01/05
AHO, Alfred V.; HOPCROFT, John E. & ULLMAN, Jeffrey D. Data structure and algorithms. Delaware: Addison-Wesley, 1983 CELES, W.; CERQUEIRA; R. F. G. & NETTO, J. L. M. R. Introduo a Estruturas de Dados - com tcnicas de programao em C. Rio de Janeiro: Campus, 2004 CAPPER, D. M. Introducing C++ for scientists, engineers and mathematicians. London: SpringerVerlag, 1994
Referncias 02/05
CORMEN, T. H.; LEISERSON, C. E.; RIVEST, R. L. & STEIN, C. Introduction to Algorithms. 2. Ed. Cidade: The MIT Press and McGraw-Hill, 2001 KERNIGHAN, B. W. C. & RITCHIE, D. M. The C Programming Language - ANSI C. Prentice Hall, 1988 KNUTH, D. E. Art of Computer Programming, Vol.1, Fundamental Algorithms (3rd Ed.), AddisonWesley, 1997 LOUDON, K. Dominando algoritmos cm C. Rio de Janeiro: Ed. Cincia Moderna, 2000.
Referncias 03/05
KORFHAGE, Robert R. Lgica y Algoritmos: Con aplicaciones a las ciencias de la computacin e informacin. Mxico D.F.: Editorial Limusa-Wiley, 1970 SABESTA, Robert. Conceitos de linguagem de programao. Editora Bookman, 2003 SEDGEWICK, R. Algorithms in C++, (3rd Ed.) Boston: Addison-Wesley Publishing Company, 1998 SZWARCFITER, J. L. & MARKENZON, L. Estruturas de Dados e seus Algoritmos. 2nd ed. Rio de Janeiro: LTC, 1994
Referncias 04/05
TENENBAUM, A. M.; LANGSAM, Y. & AUGENSTEIN, M. J. Estruturas de Dados Usando C. So Paulo: Makron Books do Brasil, 1995 TREMBLAY, J. P. & SORENSON, P.G. An introduction to data structures with applications. 2. Ed. Auckland: McGraw-Hill, 1984 WIRTH, N. Algoritmos e Estruturas de Dados, Rio de Janeiro: Prentice-Hall do Brasil, 1989
Referncias 05/05
Digresso 01/03
Digresso 02/03
// Diretivas de pr-processamento #include <stdio.h> // Prottipo das funes - Padro: (tipo) Funo (parmetros); int funcao1([parmetros]); // Definio das variveis Globais e Externas ... // Programa principal main() { // Definio das variveis locais ... // Corpo (i.e. bloco de instrues) ... // Retorno da funo (opcional em alguns casos) return [valor(es)]; } // Corpo da funo declarada anteriormente int funcao1([parmetros]) { // Definio das variveis locais ... // Corpo (i.e. bloco de instrues) ... // Retorno da funo (opcional em alguns casos) return [valor(es)]; }
Definies prvias
Digresso 03/03