capítulo ix – ponteiros

95
Capítulo IX – Ponteiros Capítulo IX – Ponteiros 9.1 – Introdução 9.1 – Introdução 9.2 – Relação entre ponteiros e variáveis 9.2 – Relação entre ponteiros e variáveis indexadas indexadas 9.3 – Alocação dinâmica de memória 9.3 – Alocação dinâmica de memória 9.4 – Variáveis indexadas, ponteiros e 9.4 – Variáveis indexadas, ponteiros e estruturas como parâmetros e elementos estruturas como parâmetros e elementos de retorno de retorno 9.5 – Subprogramas como parâmetros 9.5 – Subprogramas como parâmetros 9.6 – Encadeamento de estruturas 9.6 – Encadeamento de estruturas

Upload: iman

Post on 18-Mar-2016

34 views

Category:

Documents


0 download

DESCRIPTION

Capítulo IX – Ponteiros. 9.1 – Introdução 9.2 – Relação entre ponteiros e variáveis indexadas 9.3 – Alocação dinâmica de memória 9.4 – Variáveis indexadas, ponteiros e estruturas como parâmetros e elementos de retorno 9.5 – Subprogramas como parâmetros 9.6 – Encadeamento de estruturas. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Capítulo IX – Ponteiros

Capítulo IX – PonteirosCapítulo IX – Ponteiros

9.1 – Introdução9.1 – Introdução9.2 – Relação entre ponteiros e variáveis 9.2 – Relação entre ponteiros e variáveis

indexadasindexadas9.3 – Alocação dinâmica de memória9.3 – Alocação dinâmica de memória9.4 – Variáveis indexadas, ponteiros e 9.4 – Variáveis indexadas, ponteiros e

estruturas como parâmetros e elementos estruturas como parâmetros e elementos de retornode retorno

9.5 – Subprogramas como parâmetros9.5 – Subprogramas como parâmetros9.6 – Encadeamento de estruturas9.6 – Encadeamento de estruturas

Page 2: Capítulo IX – Ponteiros

9.3 – Alocação Dinâmica de 9.3 – Alocação Dinâmica de MemóriaMemória

9.3.1 – Dispositivos para alocação 9.3.1 – Dispositivos para alocação dinâmica dinâmica

Muitas vezes é desejável Muitas vezes é desejável reservar espaçoreservar espaço para vetores e matrizes somente em para vetores e matrizes somente em tempo de tempo de execuçãoexecução

Exemplo:Exemplo: seja a seguinte declaração: seja a seguinte declaração:

int A[100][100];int A[100][100];

Page 3: Capítulo IX – Ponteiros

int A[100][100];int A[100][100];

Neste exemplo, supõe-se que o Neste exemplo, supõe-se que o número de linhas número de linhas e colunase colunas de de AA devam ser lidos devam ser lidos durante a durante a execuçãoexecução desse programa desse programa

Caso eles sejam Caso eles sejam bem menores que 100bem menores que 100, haverá , haverá grande grande desperdíciodesperdício de memória de memória

Caso sejam Caso sejam maiores que 100maiores que 100, o espaço reservado , o espaço reservado não será suficientenão será suficiente para guardar os elementos de para guardar os elementos de AA

É conveniente É conveniente alocar espaçoalocar espaço para os elementos para os elementos dessa variável dessa variável depois de conhecidosdepois de conhecidos os números os números de linhas e de colunasde linhas e de colunas

Page 4: Capítulo IX – Ponteiros

Na Linguagem C, a Na Linguagem C, a alocação de espaço em alocação de espaço em tempo de execuçãotempo de execução para vetores e matrizes para vetores e matrizes só pode ser feita se só pode ser feita se esses forem declarados esses forem declarados como como ponteirosponteiros

Esse tipo de alocação Esse tipo de alocação denomina-se denomina-se alocação alocação dinâmicadinâmica

Há uma região da Há uma região da memória ocupada pelo memória ocupada pelo programa denominada programa denominada heapheap, destinada a essas , destinada a essas alocações dinâmicasalocações dinâmicas

Page 5: Capítulo IX – Ponteiros

A alocação pode ser A alocação pode ser feita pela função feita pela função mallocmalloc do arquivo do arquivo stdlib.hstdlib.h

mallocmalloc recebe como recebe como argumento o número de argumento o número de bytes a ser alocadobytes a ser alocado

malloc malloc então reserva na então reserva na heapheap esse número de esse número de bytes de forma contíguabytes de forma contígua

O valor retornado por O valor retornado por malloc malloc é o endereço do é o endereço do primeiro desses bytes primeiro desses bytes (um ponteiro)(um ponteiro)

Esses bytes ficam Esses bytes ficam indisponíveis para indisponíveis para novas alocaçõesnovas alocações

Page 6: Capítulo IX – Ponteiros

Exemplo: Exemplo: para alocar um vetor de 7 elementos para alocar um vetor de 7 elementos do tipo do tipo intint::

int *V;int *V;V = (int *) malloc (7 * sizeof (int));V = (int *) malloc (7 * sizeof (int));

heap

V

A conversão (int *) é necessária pois malloc retorna um ponteiro do tipo void

int

4 bytes

28 bytes

V pode ser usada como vetor

Page 7: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>typedef int *vetor;typedef int *vetor;int main () {int main () {

int m, i; vetor A, B, C;int m, i; vetor A, B, C;printf ("Tamanho dos vetores: "); scanf ("%d", &m);printf ("Tamanho dos vetores: "); scanf ("%d", &m);A = (int *) malloc (m*sizeof(int));A = (int *) malloc (m*sizeof(int));B = (int *) malloc (m*sizeof(int));B = (int *) malloc (m*sizeof(int));C = (int *) malloc (m*sizeof(int))C = (int *) malloc (m*sizeof(int));;printf ("\nVetor A: ");printf ("\nVetor A: ");for (i = 0; i < m; i++) scanf ("%d", &A[i]);for (i = 0; i < m; i++) scanf ("%d", &A[i]);printf ("\nVetor B: ");printf ("\nVetor B: ");for (i = 0; i < m; i++) scanf ("%d", &B[i]);for (i = 0; i < m; i++) scanf ("%d", &B[i]);printf ("\nVetor C: ");printf ("\nVetor C: ");for (i = 0; i < m; i++)for (i = 0; i < m; i++)

C[i] = (A[i] > B[i])? A[i]: B[i];C[i] = (A[i] > B[i])? A[i]: B[i];for (i = 0; i < m; i++) printf ("%5d", C[i]);for (i = 0; i < m; i++) printf ("%5d", C[i]);

printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

Exemplo: seja o programa à esquerda

Tamanho dos vetores: 7

Vetor A: 28 39 84 27 82 49 10

Vetor B: 94 27 68 17 83 72 39

Vetor C: 94 39 84 27 83 72 39

Digite algo para encerrar:

No vídeo

Page 8: Capítulo IX – Ponteiros

O O lay-outlay-out da área da área ocupada pelo ocupada pelo programa é planejado programa é planejado pelo pelo compiladorcompilador

O O gerenciamentogerenciamento durante a execução durante a execução fica por conta do fica por conta do próprio próprio programaprograma

A A área totalárea total reservada reservada para o programa é para o programa é fixafixa

As regiões das As regiões das instruçõesinstruções e das e das variáveis globais variáveis globais também tem tamanho também tem tamanho fixofixo

Page 9: Capítulo IX – Ponteiros

As outras regiões tem As outras regiões tem tamanho variável tamanho variável durante a execução durante a execução

A A área de dados das área de dados das funçõesfunções destina-se a destina-se a guardar os parâmetros, guardar os parâmetros, as variáveis locais e as variáveis locais e informações informações operacionais das operacionais das versões ativas de versões ativas de funções funções num dado num dado momentomomento

Essa área Essa área varia de varia de tamanhotamanho, pois essas , pois essas versões de funções não versões de funções não ficam ativas o tempo ficam ativas o tempo todotodo

Page 10: Capítulo IX – Ponteiros

Quando uma versão Quando uma versão de função é chamada de função é chamada para execução, sua para execução, sua área de dados é área de dados é carregadacarregada na na memóriamemória

O carregamento é O carregamento é feito a partir da feito a partir da fronteira com a fronteira com a área área desocupadadesocupada

Quando sua execução Quando sua execução é encerrada, sua é encerrada, sua área área é retiradaé retirada da da memória, memória, aumentando a área aumentando a área desocupadadesocupada

Page 11: Capítulo IX – Ponteiros

A área A área heapheap aumenta aumenta a partir de sua a partir de sua fronteira com a fronteira com a área área desocupadadesocupada

Isso acontece quando Isso acontece quando uma uma alocação alocação dinâmicadinâmica de memória de memória é feita (é feita (malloc malloc ou ou outras do gênero) outras do gênero)

A A área de dadosárea de dados das das funções aumenta funções aumenta para para baixobaixo e a e a heapheap aumenta para aumenta para cimacima

Page 12: Capítulo IX – Ponteiros

Nesse processo, se o Nesse processo, se o programador não programador não tomar cuidado, essas tomar cuidado, essas duas áreas podem se duas áreas podem se encontrarencontrar

Aí, Aí, esgota-seesgota-se a a capacidade da capacidade da área área desocupadadesocupada

Novas chamadas de Novas chamadas de funções e novas funções e novas alocações dinâmicas alocações dinâmicas ficam ficam impossibilitadasimpossibilitadas

Page 13: Capítulo IX – Ponteiros

A função A função freefree torna a torna a deixar disponível a deixar disponível a área reservada área reservada numa numa alocação dinâmicaalocação dinâmica

Seu parâmetro é um Seu parâmetro é um ponteiro ponteiro

Ela Ela re-disponibilizare-disponibiliza a a área previamente área previamente alocada e apontada alocada e apontada por elepor ele

Deve-se usar essa Deve-se usar essa função toda vez que função toda vez que uma alocação não uma alocação não tiver mais utilidade tiver mais utilidade para o programapara o programa

Page 14: Capítulo IX – Ponteiros

9.3.2 – Alocação dinâmica de matrizes 9.3.2 – Alocação dinâmica de matrizes Usa-se Usa-se ponteiro ponteiro para para vetor de ponteiros:vetor de ponteiros:

Ver programa a seguir

Page 15: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>

typedef int **matriz;typedef int **matriz;int main () {int main () {

int m, n, i, j; int m, n, i, j; matriz A;matriz A;printf ("Dimensoes de uma matriz: ");printf ("Dimensoes de uma matriz: ");scanf ("%d%d", &m, &n);scanf ("%d%d", &m, &n);A = (int **) malloc (m * sizeof(int*));A = (int **) malloc (m * sizeof(int*));for (i = 0; i < m; i++)for (i = 0; i < m; i++)

A[i]= (int *) malloc (n * sizeof(int));A[i]= (int *) malloc (n * sizeof(int));printf ("\nElementos da matriz:\n\n");printf ("\nElementos da matriz:\n\n");for (i = 0; i < m; i++) {for (i = 0; i < m; i++) {

printf ("\tLinha %d: ", i);printf ("\tLinha %d: ", i);for (j = 0; j < n; j++)for (j = 0; j < n; j++)

scanf ("%d", &A[i][j]);scanf ("%d", &A[i][j]);}}printf ("\nConfirmacao: \n\n");printf ("\nConfirmacao: \n\n");for (i = 0; i < m; i++) {for (i = 0; i < m; i++) {

for (j = 0; j < n; j++)for (j = 0; j < n; j++)printf ("%5d", A[i][j]);printf ("%5d", A[i][j]);

printf ("\n");printf ("\n");}}

printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

matriz é o tipo ponteiro para ponteiros de int

A partir deste ponto, A pode ser usada como uma matriz comum

Page 16: Capítulo IX – Ponteiros

Capítulo IX – PonteirosCapítulo IX – Ponteiros

9.1 – Introdução9.1 – Introdução9.2 – Relação entre ponteiros e variáveis 9.2 – Relação entre ponteiros e variáveis

indexadasindexadas9.3 – Alocação dinâmica de memória9.3 – Alocação dinâmica de memória9.4 – Variáveis indexadas, ponteiros e 9.4 – Variáveis indexadas, ponteiros e

estruturas como parâmetros e elementos estruturas como parâmetros e elementos de retornode retorno

9.5 – Subprogramas como parâmetros9.5 – Subprogramas como parâmetros9.6 – Encadeamento de estruturas9.6 – Encadeamento de estruturas

Page 17: Capítulo IX – Ponteiros

9.4 – Variáveis Indexadas, 9.4 – Variáveis Indexadas, Ponteiros e Estruturas como Ponteiros e Estruturas como Parâmetros e Elementos de Parâmetros e Elementos de

RetornoRetorno9.4.1 – Variáveis indexadas e ponteiros 9.4.1 – Variáveis indexadas e ponteiros

como parâmetros como parâmetros

Em C, quando Em C, quando um dos parâmetrosum dos parâmetros de uma de uma função for declarado como função for declarado como variável indexadavariável indexada, , na realidade ele será um na realidade ele será um ponteiroponteiro

Page 18: Capítulo IX – Ponteiros

Caso o argumento correspondente seja o Caso o argumento correspondente seja o nome de nome de uma variável indexadauma variável indexada: :

O O endereçoendereço correspondente aos seu correspondente aos seu nomenome é é passado ao passado ao ponteiro-parâmetroponteiro-parâmetro

Os Os elementoselementos da variável-argumento da variável-argumento não são não são copiadoscopiados para a função para a função

Então essa Então essa passagempassagem de argumento é de argumento é por por referênciareferência

Toda Toda alteraçãoalteração nos elementos da nos elementos da variável-variável-parâmetroparâmetro terá efeito sobre aqueles da terá efeito sobre aqueles da variável-variável-argumentoargumento

Outros possíveis argumentos: Outros possíveis argumentos: ponteiros e ponteiros e endereçosendereços

Page 19: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>

void Alterar (int B[]) {void Alterar (int B[]) {B[1] = B[3] = 7;B[1] = B[3] = 7;

}}

int main () {int main () {int i, int i, A[10] = {0};A[10] = {0};printf ("Vetor inicial : ");printf ("Vetor inicial : ");for (i = 0; i <= 9; i++)for (i = 0; i <= 9; i++)

printf ("%3d", A[i]);printf ("%3d", A[i]);Alterar (A);Alterar (A);printf ("\n\nVetor intermediario: ");printf ("\n\nVetor intermediario: ");for (i = 0; i <= 9; i++) printf ("%3d", A[i]);for (i = 0; i <= 9; i++) printf ("%3d", A[i]);Alterar (&A[4]);Alterar (&A[4]);printf ("\n\nVetor final : ");printf ("\n\nVetor final : ");for (i = 0; i <= 9; i++) printf ("%3d", A[i]);for (i = 0; i <= 9; i++) printf ("%3d", A[i]);

printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

Exemplo: seja o programa à esquerda

O parâmetro B de Alterar é um ponteiro

Não é necessário colocar a dimensão

Poderia ser int *B

Page 20: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>

void Alterar (int B[]) {void Alterar (int B[]) {B[1] = B[3] = 7;B[1] = B[3] = 7;

}}

int main () {int main () {int i, A[10] = {0};int i, A[10] = {0};printf ("Vetor inicial : ");printf ("Vetor inicial : ");for (i = 0; i <= 9; i++)for (i = 0; i <= 9; i++)

printf ("%3d", A[i]);printf ("%3d", A[i]);Alterar (A);Alterar (A);printf ("\n\nVetor intermediario: ");printf ("\n\nVetor intermediario: ");for (i = 0; i <= 9; i++) printf ("%3d", A[i]);for (i = 0; i <= 9; i++) printf ("%3d", A[i]);Alterar (&A[4]);Alterar (&A[4]);printf ("\n\nVetor final : ");printf ("\n\nVetor final : ");for (i = 0; i <= 9; i++) printf ("%3d", A[i]);for (i = 0; i <= 9; i++) printf ("%3d", A[i]);

printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

A

A[0]A[1]A[2]A[3]A[4]A[5]A[6]A[7]A[8]A[9]0 0 0 0 0 0 0 0 0 0

B

B[0]B[1]B[2]B[3]B[4]B[5]B[6]B[7]B[8]B[9]

7 7

B[0]B[1]B[2]B[3]B[4]B[5]

7 7

Page 21: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>

void Alterar (int B[]) {void Alterar (int B[]) {B[1] = B[3] = 7;B[1] = B[3] = 7;

}}

int main () {int main () {int i, A[10] = {0};int i, A[10] = {0};printf ("Vetor inicial : ");printf ("Vetor inicial : ");for (i = 0; i <= 9; i++)for (i = 0; i <= 9; i++)

printf ("%3d", A[i]);printf ("%3d", A[i]);Alterar (A);Alterar (A);printf ("\n\nVetor intermediario: ");printf ("\n\nVetor intermediario: ");for (i = 0; i <= 9; i++) printf ("%3d", A[i]);for (i = 0; i <= 9; i++) printf ("%3d", A[i]);Alterar (&A[4]);Alterar (&A[4]);printf ("\n\nVetor final : ");printf ("\n\nVetor final : ");for (i = 0; i <= 9; i++) printf ("%3d", A[i]);for (i = 0; i <= 9; i++) printf ("%3d", A[i]);

printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

Vetor inicial : 0 0 0 0 0 0 0 0 0 0

Vetor intermediario: 0 7 0 7 0 0 0 0 0 0

Vetor final : 0 7 0 7 0 7 0 7 0 0

Pressione ...

Resultado

Page 22: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>

void ImprimirMatriz (int V[][10], int x, int y) {void ImprimirMatriz (int V[][10], int x, int y) { int i, j;int i, j; printf ("Endereco(V) = %d; Conteudo(V) = %d;\n\n", &V, V);printf ("Endereco(V) = %d; Conteudo(V) = %d;\n\n", &V, V); printf ("Endereco(V[0][0]) = %d\n\n", &V[0][0]);printf ("Endereco(V[0][0]) = %d\n\n", &V[0][0]); for (i = 0; i < x; i++) {for (i = 0; i < x; i++) { for (j = 0; j < y; j++) {for (j = 0; j < y; j++) { printf ("%5d", V[i][j]);printf ("%5d", V[i][j]); }} printf ("\n");printf ("\n"); }}}}

int main () {int main () {int A[10][10], i, j, m = 5, n = 7;int A[10][10], i, j, m = 5, n = 7;printf ("A = %d\n\n", A);printf ("A = %d\n\n", A);

printf ("Endereco(A[0][0]) = %d\n\n", &A[0][0]);printf ("Endereco(A[0][0]) = %d\n\n", &A[0][0]); for (i = 0; i < m; i++)for (i = 0; i < m; i++) for (j = 0; j < n; j++) for (j = 0; j < n; j++) A[i][j] = (i+1)*(j+1);A[i][j] = (i+1)*(j+1);

ImprimirMatriz (A, m, n);ImprimirMatriz (A, m, n);getch ();getch ();

}}

Exemplo com matriz bidimensional

Page 23: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>

void ImprimirMatriz (void ImprimirMatriz (int V[][10], int V[][10], int x, int y) {int x, int y) { int i, j;int i, j; printf ("Endereco(V) = %d; Conteudo(V) = %d;\n\n", &V, V);printf ("Endereco(V) = %d; Conteudo(V) = %d;\n\n", &V, V); printf ("Endereco(V[0][0]) = %d\n\n", &V[0][0]);printf ("Endereco(V[0][0]) = %d\n\n", &V[0][0]); for (i = 0; i < x; i++) {for (i = 0; i < x; i++) { for (j = 0; j < y; j++) {for (j = 0; j < y; j++) { printf ("%5d", V[i][j]);printf ("%5d", V[i][j]); }} printf ("\n");printf ("\n"); }}}}

int main () {int main () {int A[10][10], i, j, m = 5, n = 7;int A[10][10], i, j, m = 5, n = 7;printf ("A = %d\n\n", A);printf ("A = %d\n\n", A);

printf ("Endereco(A[0][0]) = %d\n\n", &A[0][0]);printf ("Endereco(A[0][0]) = %d\n\n", &A[0][0]); for (i = 0; i < m; i++)for (i = 0; i < m; i++) for (j = 0; j < n; j++) for (j = 0; j < n; j++) A[i][j] = (i+1)*(j+1);A[i][j] = (i+1)*(j+1);

ImprimirMatriz (A, m, n);ImprimirMatriz (A, m, n);getch ();getch ();

}}

No parâmetro V, a 1ª dimensão é dispensada

Resultado

Page 24: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>

void ImprimirMatriz (void ImprimirMatriz (int V[][10], int V[][10], int x, int y) {int x, int y) { int i, j;int i, j; printf ("Endereco(V) = %d; Conteudo(V) = %d;\n\n", &V, V);printf ("Endereco(V) = %d; Conteudo(V) = %d;\n\n", &V, V); printf ("Endereco(V[0][0]) = %d\n\n", &V[0][0]);printf ("Endereco(V[0][0]) = %d\n\n", &V[0][0]); for (i = 0; i < x; i++) {for (i = 0; i < x; i++) { for (j = 0; j < y; j++) {for (j = 0; j < y; j++) { printf ("%5d", V[i][j]);printf ("%5d", V[i][j]); }} printf ("\n");printf ("\n"); }}}}

int main () {int main () {int A[10][10], i, j, m = 5, n = 7;int A[10][10], i, j, m = 5, n = 7;printf ("A = %d\n\n", A);printf ("A = %d\n\n", A);

printf ("Endereco(A[0][0]) = %d\n\n", &A[0][0]);printf ("Endereco(A[0][0]) = %d\n\n", &A[0][0]); for (i = 0; i < m; i++)for (i = 0; i < m; i++) for (j = 0; j < n; j++) {for (j = 0; j < n; j++) { A[i][j] = (i+1)*(j+1);A[i][j] = (i+1)*(j+1); }} ImprimirMatriz (A, m, n);ImprimirMatriz (A, m, n);

printf ("\n\n"); system ("pause");printf ("\n\n"); system ("pause"); return 0;return 0;}}

Resultado

AA[0][0]

V

Page 25: Capítulo IX – Ponteiros

Exemplo: Fusão de 2 vetores ordenadosExemplo: Fusão de 2 vetores ordenados

O programa a seguir realiza as seguintes O programa a seguir realiza as seguintes operações:operações:

LêLê os dados sobre os dois vetores os dados sobre os dois vetores

OrdenaOrdena-os pelo -os pelo Bubble-SortBubble-Sort

FundeFunde os dois vetores pelo método os dois vetores pelo método Merge-Merge-SortSort, obtendo um terceiro vetor , obtendo um terceiro vetor ordenadoordenado

O método O método Merge-SortMerge-Sort apresentado apresentado só funciona só funciona quando os 2 vetores já estão quando os 2 vetores já estão ordenadosordenados

Page 26: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 27: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 28: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 29: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 30: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5 5

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 31: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5 5 6

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 32: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5 5 6 7

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 33: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5 5 6 7 8

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 34: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5 5 6 7 8 8

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 35: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5 5 6 7 8 8 8

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 36: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5 5 6 7 8 8 8 9

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

Page 37: Capítulo IX – Ponteiros

O Método Merge-Sort:O Método Merge-Sort:

3 4 5 5 6 7 8 8 8 9 11

13

16

3 5 8 8 11

13

16

4 5 6 7 8 9

V1

V2

V3

i

j

k

V3[k] = (V1[i] < V2[j]) ? V1[i] : V2[j];

A seguir, o programa

Page 38: Capítulo IX – Ponteiros

/*/* Declaracoes globais */Declaracoes globais */

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>typedef char logic;typedef char logic;const logic TRUE = 1, FALSE = 0;const logic TRUE = 1, FALSE = 0;typedef int vetor[20];typedef int vetor[20];

/*/* Prototipos das funcoes auxiliaresPrototipos das funcoes auxiliares */*/

void LerVetor (vetor, int*);void LerVetor (vetor, int*);void EscreverVetor (vetor, int);void EscreverVetor (vetor, int);void BubbleSort (vetor, int);void BubbleSort (vetor, int);void MergeSort (vetor, vetor, vetor, int, int, int*);void MergeSort (vetor, vetor, vetor, int, int, int*);

O tipo dos parâmetros dos protótipos devem ser os mesmos nas definições das funções

Page 39: Capítulo IX – Ponteiros

int main () {int main () {int m, n, p;int m, n, p;vetor V1, V2, V3;vetor V1, V2, V3;

printf ("FUSAO DE DOIS VETORES ORDENADOS");printf ("FUSAO DE DOIS VETORES ORDENADOS");

/*/* Leitura dos dois vetoresLeitura dos dois vetores */*/

printf ("\n\nLeitura do vetor V1: \n");printf ("\n\nLeitura do vetor V1: \n"); LerVetor (V1, &m);LerVetor (V1, &m);

printf ("\nLeitura do vetor V2: \n");printf ("\nLeitura do vetor V2: \n"); LerVetor (V2, &n);LerVetor (V2, &n);

/*/* Escrita dos dois vetores lidosEscrita dos dois vetores lidos */*/

printf ("\n\nVetor V1 inicial: \n\n");printf ("\n\nVetor V1 inicial: \n\n");EscreverVetor (V1, m);EscreverVetor (V1, m);

printf ("\n\nVetor V2 inicial: \n\n");printf ("\n\nVetor V2 inicial: \n\n");EscreverVetor (V2, n);EscreverVetor (V2, n);

V1, V2 e V3 são variáveis indexadas

Passagem de V1, V2, m e n: por referênciaEles serão alterados pela função LerVetorPassagem de V1 e V2 : por referência

Os elementos não precisam ser copiados para a função

Page 40: Capítulo IX – Ponteiros

/*/* Ordenacao e escrita dos dois vetores ordenados */Ordenacao e escrita dos dois vetores ordenados */

BubbleSort (V1, m);BubbleSort (V1, m);BubbleSort (V2, n);BubbleSort (V2, n);

printf ("\n\nVetor V1 ordenado: \n\n");printf ("\n\nVetor V1 ordenado: \n\n");EscreverVetor (V1, m);EscreverVetor (V1, m);

printf ("\n\nVetor V2 ordenado: \n\n");printf ("\n\nVetor V2 ordenado: \n\n");EscreverVetor (V2, n);EscreverVetor (V2, n);

/*/* Fusao dos dois vetores num terceiro */Fusao dos dois vetores num terceiro */

MergeSort (V1, V2, V3, m, n, &p);MergeSort (V1, V2, V3, m, n, &p);

Passagem de V1 e V2: por referênciaEles serão alterados pela função BubbleSort

Passagem de V1 e V2: por referênciaOs elementos não precisam ser copiados para a função

Passagem de V3 e p: por referênciaEles serão alterados pela função MergeSort

Page 41: Capítulo IX – Ponteiros

/*/* Escrita do vetor resultado da fusao */Escrita do vetor resultado da fusao */

printf ("\n\nFusao V3 dos vetores V1 e V2:\n\n");printf ("\n\nFusao V3 dos vetores V1 e V2:\n\n");EscreverVetor (V3, p);EscreverVetor (V3, p);

/*/* Fechamento da tela */Fechamento da tela */

printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

Page 42: Capítulo IX – Ponteiros

/*/* Funcao LerVetor para ler os elementos de um vetor */Funcao LerVetor para ler os elementos de um vetor */

void LerVetor (vetor V, int *n)void LerVetor (vetor V, int *n) { { int i;int i;

printf ("\n\tNumero de elementos: ");printf ("\n\tNumero de elementos: ");scanf ("%d", n);scanf ("%d", n);printf ("\n\tSeus %d elementos: ", printf ("\n\tSeus %d elementos: ", *n*n););for (i = 0; i <= for (i = 0; i <= *n-1*n-1; i++); i++)

scanf ("%d", scanf ("%d", &V[i]&V[i]););}}

/*/* Funcao EscreverVetor para escrever os elementos de um Funcao EscreverVetor para escrever os elementos de um vetor */vetor */

void EscreverVetor (vetor V, int n) {void EscreverVetor (vetor V, int n) {int i;int i;for (i = 0; i <= n-1; i++)for (i = 0; i <= n-1; i++)

printf ("%4d", printf ("%4d", V[i]V[i]););}}

Na função main:LerVetor (V1, &m); LerVetor (V2, &n);Não é &n, pois n já é o endereço alvoLocal apontado por n

V[i] coincide com os elementos V1[i] e V2[i] dos argumentos V1 e V2

Page 43: Capítulo IX – Ponteiros

/*/* Funcao BubbleSort para ordenar os elementos de um vetor Funcao BubbleSort para ordenar os elementos de um vetor */ */

void BubbleSort (vetor V, int n) {void BubbleSort (vetor V, int n) {int i, p, aux; logic trocou;int i, p, aux; logic trocou;p = n-2; trocou = TRUE;p = n-2; trocou = TRUE;while (p>=0 && trocou) {while (p>=0 && trocou) {

trocou = FALSE; i = 0;trocou = FALSE; i = 0;while (i <= p) {while (i <= p) {

if (if (V[i] > V[i+1]V[i] > V[i+1]) {) {aux = aux = V[i]V[i]; ; V[i]V[i] = = V[i+1]V[i+1];;V[i+1]V[i+1] = aux; trocou = TRUE; = aux; trocou = TRUE;

}}i = i+1;i = i+1;

}}p = p-1;p = p-1;

}}}}

V[i] e V[i+1] coincidem com os elementos correspondentes dos argumentos V1 e V2

Na função main:BubbleSort (V1, m);BubbleSort (V2, n);

Page 44: Capítulo IX – Ponteiros

/*/* Funcao MergeSort para fundir dois vetoresFuncao MergeSort para fundir dois vetoresordenados num terceiro tambem ordenadoordenados num terceiro tambem ordenado */*/

void MergeSort (vetor V1, vetor V2, vetor V3, int m, void MergeSort (vetor V1, vetor V2, vetor V3, int m, int n, int *p) {int n, int *p) {int i, j, k;int i, j, k;

*p = m + n;*p = m + n;for (i = j = k = 0; i < m && j < n; k++)for (i = j = k = 0; i < m && j < n; k++)

if (V1[i] < V2[j]) {if (V1[i] < V2[j]) {V3[k] = V1[i]; i++;V3[k] = V1[i]; i++;

}}else {else {

V3[k] = V2[j]; j++;V3[k] = V2[j]; j++;}}

for (; i < m; i++, k++) V3[k] = V1[i];for (; i < m; i++, k++) V3[k] = V1[i];for (; j < n; j++, k++) V3[k] = V2[j];for (; j < n; j++, k++) V3[k] = V2[j];

}}

Na função main:MergeSort (V1, V2, V3, m, n, &p);

O tamanho do vetor final é calculado pela MergeSortPercurso em V1 e V2 ainda

não acabou

Percurso em V1 ou V2 acabou

Page 45: Capítulo IX – Ponteiros

9.4.2 – Variáveis indexadas e ponteiros 9.4.2 – Variáveis indexadas e ponteiros como valores retornados como valores retornados

Quando se deseja produzir uma Quando se deseja produzir uma variável variável indexadaindexada dentro de uma função e dentro de uma função e retornar retornar seus elementosseus elementos, deve-se usar um , deve-se usar um ponteiroponteiro

O programa a seguir faz O programa a seguir faz alocação dinâmicaalocação dinâmica de uma de uma matrizmatriz dentro de uma dentro de uma função auxiliarfunção auxiliar

As As dimensõesdimensões são passadas por são passadas por referênciareferência e e lidas na própria funçãolidas na própria função

O O ponteiroponteiro para os para os elementoselementos da matriz é o da matriz é o valor de valor de retornoretorno

Page 46: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>typedef int **matriz;typedef int **matriz;

matriz LerMatriz (int*, int*);matriz LerMatriz (int*, int*);void EscreverMatriz (matriz, int, int);void EscreverMatriz (matriz, int, int);

int main () {int main () {int m, n; matriz A;int m, n; matriz A;printf ("Leitura da matriz A\n\n");printf ("Leitura da matriz A\n\n");

A = LerMatriz (&m, &n);A = LerMatriz (&m, &n);printf ("\nMatriz A lida:\n\n");printf ("\nMatriz A lida:\n\n");

EscreverMatriz (A, m, n);EscreverMatriz (A, m, n); printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

O valor retornado de LerMatriz é atribuído a A

Page 47: Capítulo IX – Ponteiros

matriz LerMatriz (int *nlin, int *ncol) {matriz LerMatriz (int *nlin, int *ncol) {

matriz MatRetorno; int i, j;matriz MatRetorno; int i, j; printf ("Digite as 2 dimensoes: ");printf ("Digite as 2 dimensoes: ");

scanf ("%d%d", nlin, ncol);scanf ("%d%d", nlin, ncol);MatRetorno = (int **) malloc (*nlin * sizeof(int*));MatRetorno = (int **) malloc (*nlin * sizeof(int*));for (i = 0; i < *nlin; i++)for (i = 0; i < *nlin; i++)

MatRetorno[i]= (int *) malloc (*ncol * MatRetorno[i]= (int *) malloc (*ncol * sizeof(int));sizeof(int));printf ("\nDigite os elementos da matriz\n\n");printf ("\nDigite os elementos da matriz\n\n");for (i = 0; i < *nlin; i++) {for (i = 0; i < *nlin; i++) {

printf ("\tLinha %d: ", i);printf ("\tLinha %d: ", i);for (j = 0; j < *ncol; j++)for (j = 0; j < *ncol; j++)

scanf ("%d", &MatRetorno[i][j]);scanf ("%d", &MatRetorno[i][j]);}}

return MatRetorno;return MatRetorno;}}

Na função main:A = LerMatriz (&m, &n);

Alocação do vetor de ponteiros

O valor retornado é um ponteiro

Page 48: Capítulo IX – Ponteiros

void EscreverMatriz (matriz Mat, int m, int n) {void EscreverMatriz (matriz Mat, int m, int n) {int i, j;int i, j;for (i = 0; i < m; i++) {for (i = 0; i < m; i++) {

for (j = 0; j < n; j++)for (j = 0; j < n; j++)printf ("%5d", Mat[i][j]);printf ("%5d", Mat[i][j]);

printf ("\n");printf ("\n");}}

}}

Na função main:EscreverMatriz (A, m, n);

Page 49: Capítulo IX – Ponteiros

9.4.3 – Estruturas como parâmetros e 9.4.3 – Estruturas como parâmetros e valores retornados valores retornados

Em C, Em C, estruturasestruturas podem ser declaradas como podem ser declaradas como parâmetrosparâmetros, passadas como argumentos, passadas como argumentos por por valorvalor e por e por referênciareferência e seus valores podem e seus valores podem ser ser retornadosretornados de funções de funções

Na passagem de Na passagem de argumento por valorargumento por valor e no e no retornoretorno de uma função, há uma de uma função, há uma cópia de toda cópia de toda a estruturaa estrutura, de um módulo para outro, de um módulo para outro

O programa a seguir realiza operações com O programa a seguir realiza operações com números complexosnúmeros complexos

É usada uma É usada uma estruturaestrutura com a parte com a parte realreal e a e a parte parte imagináriaimaginária de um de um complexocomplexo

Page 50: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <conio.h>#include <conio.h>#include <conio2.h>#include <conio2.h>#include <stdlib.h>#include <stdlib.h>#include <math.h>#include <math.h>

struct complexo {float real, imag;};struct complexo {float real, imag;};typedef struct complexo complexo;typedef struct complexo complexo;

void WriteMenu (void);void WriteMenu (void);complexo Soma (complexo, complexo);complexo Soma (complexo, complexo);complexo Subtracao (complexo, complexo);complexo Subtracao (complexo, complexo);complexo Multiplicacao (complexo, complexo);complexo Multiplicacao (complexo, complexo);complexo Divisao (complexo, complexo);complexo Divisao (complexo, complexo);

Nas funções para operações com complexo, todos os parâmetros e os valores retornados são estruturas

Page 51: Capítulo IX – Ponteiros

int main () {int main () {complexo a, b, r;complexo a, b, r; char c; char c;

WriteMenu (); c = getche (); clrscr ();WriteMenu (); c = getche (); clrscr ();

while (c != '0') {while (c != '0') { switch (c) {switch (c) { case '1':case '1': printf ("Soma de complexos\n\n");printf ("Soma de complexos\n\n"); printf ("\tDigite os dois operandos: ");printf ("\tDigite os dois operandos: "); scanf ("%f%f%f%f", &a.real, &a.imag, &b.real, &b.imag);scanf ("%f%f%f%f", &a.real, &a.imag, &b.real, &b.imag); r = Soma (a, b);r = Soma (a, b); printf ("\n[(%g)+j(%g)] + [(%g)+j(%g)] = [(%g)+j(%g)]",printf ("\n[(%g)+j(%g)] + [(%g)+j(%g)] = [(%g)+j(%g)]", a.real, a.imag, b.real, b.imag, r.real, r.imag);a.real, a.imag, b.real, b.imag, r.real, r.imag); break;break;

Page 52: Capítulo IX – Ponteiros

case '2':case '2': printf ("Subtracao de complexos\n\n");printf ("Subtracao de complexos\n\n"); printf ("\tDigite os dois operandos: ");printf ("\tDigite os dois operandos: "); scanf ("%f%f%f%f", &a.real, &a.imag, &b.real, &b.imag);scanf ("%f%f%f%f", &a.real, &a.imag, &b.real, &b.imag); r = Subtracao (a, b);r = Subtracao (a, b); printf ("\n[(%g)+j(%g)] - [(%g)+j(%g)] = [(%g)+j(%g)]",printf ("\n[(%g)+j(%g)] - [(%g)+j(%g)] = [(%g)+j(%g)]", a.real, a.imag, b.real, b.imag, r.real, r.imag);a.real, a.imag, b.real, b.imag, r.real, r.imag); break;break; case '3':case '3': printf ("Multiplicacao de complexos\n\n");printf ("Multiplicacao de complexos\n\n"); printf ("\tDigite os dois operandos: ");printf ("\tDigite os dois operandos: "); scanf ("%f%f%f%f", &a.real, &a.imag, &b.real, &b.imag);scanf ("%f%f%f%f", &a.real, &a.imag, &b.real, &b.imag); r = Multiplicacao (a, b);r = Multiplicacao (a, b); printf ("\n[(%g)+j(%g)] * [(%g)+j(%g)] = [(%g)+j(%g)]",printf ("\n[(%g)+j(%g)] * [(%g)+j(%g)] = [(%g)+j(%g)]", a.real, a.imag, b.real, b.imag, r.real, r.imag);a.real, a.imag, b.real, b.imag, r.real, r.imag); break;break;

Page 53: Capítulo IX – Ponteiros

case '4':case '4': printf ("Divisao de complexos\n\n");printf ("Divisao de complexos\n\n"); printf("\tDigite os dois operandos: "); printf("\tDigite os dois operandos: "); scanf ("%f%f%f%f", &a.real, &a.imag, &b.real, &b.imag);scanf ("%f%f%f%f", &a.real, &a.imag, &b.real, &b.imag); if (b.real == 0 && b.imag == 0)if (b.real == 0 && b.imag == 0) printf ("\nO divisor eh zero!!!");printf ("\nO divisor eh zero!!!"); else {else { r = Divisao (a, b);r = Divisao (a, b); printf("\n[(%g)+j(%g)] / [(%g)+j(%g)] = [(%g)+j(%g)]",printf("\n[(%g)+j(%g)] / [(%g)+j(%g)] = [(%g)+j(%g)]", a.real, a.imag, b.real, b.imag, r.real, r.imag);a.real, a.imag, b.real, b.imag, r.real, r.imag); }} break;break; default:default: printf ("Operacao invalida!!!");printf ("Operacao invalida!!!"); }} printf ("\n\nDigite algo para continuar"); getch ();printf ("\n\nDigite algo para continuar"); getch (); WriteMenu (); c = getche (); clrscr ();WriteMenu (); c = getche (); clrscr ();}}

printf ("Fim das operacoes!!!\n\n");printf ("Fim das operacoes!!!\n\n"); system ("pause"); return 0;system ("pause"); return 0;}}

Page 54: Capítulo IX – Ponteiros

void WriteMenu () {void WriteMenu () {clrscr ();clrscr ();printf ("OPERACOES COM NUMEROS COMPLEXOS\n\n");printf ("OPERACOES COM NUMEROS COMPLEXOS\n\n");printf ("\n\t1 - Soma");printf ("\n\t1 - Soma");printf ("\n\t2 - Subtracao");printf ("\n\t2 - Subtracao");printf ("\n\t3 - Multiplicacao");printf ("\n\t3 - Multiplicacao");printf ("\n\t4 - Divisao");printf ("\n\t4 - Divisao");printf ("\n\nDigite a operacao desejada (Zero para encerrar): ");printf ("\n\nDigite a operacao desejada (Zero para encerrar): ");

}}

complexo Soma (complexo a, complexo b) {complexo Soma (complexo a, complexo b) {complexo r;complexo r;r.real = a.real + b.real; r.imag = a.imag + b.imag;r.real = a.real + b.real; r.imag = a.imag + b.imag;return r;return r;

}}

complexo Subtracao (complexo a, complexo b) {complexo Subtracao (complexo a, complexo b) {complexo r;complexo r;r.real = a.real - b.real; r.imag = a.imag - b.imag;r.real = a.real - b.real; r.imag = a.imag - b.imag;return r;return r;

}}

Page 55: Capítulo IX – Ponteiros

complexo Multiplicacao (complexo a, complexo b) {complexo Multiplicacao (complexo a, complexo b) {complexo r;complexo r;r.real = a.real*b.real - a.imag*b.imag;r.real = a.real*b.real - a.imag*b.imag;r.imag = a.real*b.imag + a.imag*b.real;r.imag = a.real*b.imag + a.imag*b.real;return r ;return r ;

}}

complexo Divisao (complexo a, complexo b) {complexo Divisao (complexo a, complexo b) {complexo r; float denominador;complexo r; float denominador;denominador = pow (b.real, 2) + pow (b.imag, 2);denominador = pow (b.real, 2) + pow (b.imag, 2);r.real = (a.real*b.real + a.imag*b.imag) / denominador;r.real = (a.real*b.real + a.imag*b.imag) / denominador;

r.imag = (a.imag*b.real - a.real*b.imag) / denominador;r.imag = (a.imag*b.real - a.real*b.imag) / denominador;return r ;return r ;

}}

Page 56: Capítulo IX – Ponteiros

Como já foi visto, Como já foi visto, não é possívelnão é possível passar como passar como argumentos por valorargumentos por valor nem como valores a serem nem como valores a serem retornadosretornados de uma função todos os de uma função todos os elementoselementos de de uma uma variável indexadavariável indexada

Se você não pode passar um elefante por debaixo Se você não pode passar um elefante por debaixo de uma porta, coloque-o dentro de um envelope e de uma porta, coloque-o dentro de um envelope e passe-opasse-o

Se você não pode passar uma variável indexada Se você não pode passar uma variável indexada como argumento por valor ou como valor de como argumento por valor ou como valor de retorno de uma função, coloque-a dentro de uma retorno de uma função, coloque-a dentro de uma estrutura e passe-oestrutura e passe-o

A seguir, um programa para A seguir, um programa para elevar uma matriz a um elevar uma matriz a um expoenteexpoente

Ele invoca uma função para Ele invoca uma função para multiplicar duas multiplicar duas matrizesmatrizes

Page 57: Capítulo IX – Ponteiros

/*/* Declaracoes globais */Declaracoes globais */

#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <conio.h>#include <conio.h>typedef struct matriz matriz;typedef struct matriz matriz;struct matriz {struct matriz {

int nlin, ncol;int nlin, ncol;int elem[10][10];int elem[10][10];

};};

/*/* Prototipos das funcoes auxiliaresPrototipos das funcoes auxiliares */*/

void LerMatrizQuadrada (matriz *);void LerMatrizQuadrada (matriz *);void EscreverMatriz (matriz Mat);void EscreverMatriz (matriz Mat);matriz MultMat (matriz, matriz);matriz MultMat (matriz, matriz);

Page 58: Capítulo IX – Ponteiros

int main () {int main () {int p, i, j, k;int p, i, j, k;matriz M, Mpot;matriz M, Mpot;printf ("POTENCIACAO DE MATRIZ\n\n");printf ("POTENCIACAO DE MATRIZ\n\n");

/*/* Leitura do expoente Leitura do expoente */*/

printf ("Digite o expoente: ");printf ("Digite o expoente: ");scanf ("%d", &p);scanf ("%d", &p);while (p < 0) {while (p < 0) {

printf ("\tExpoente < 0; Digite novamente: ");printf ("\tExpoente < 0; Digite novamente: ");scanf ("%d", &p);scanf ("%d", &p);

}}

/*/* Leitura e escrita da matriz baseLeitura e escrita da matriz base */*/

printf ("\nLeitura da matriz base: \n");printf ("\nLeitura da matriz base: \n");LerMatrizQuadrada (&M);LerMatrizQuadrada (&M);printf ("\nMatriz lida: \n\n");printf ("\nMatriz lida: \n\n");EscreverMatriz (M);EscreverMatriz (M);printf ("\nExpoente de potenciacao: %d\n", p);printf ("\nExpoente de potenciacao: %d\n", p);

O argumento é o endereço de uma estrutura

Page 59: Capítulo IX – Ponteiros

/*/* Inicializacao da matriz potencia com a matriz identidade Inicializacao da matriz potencia com a matriz identidade */*/

Mpot.nlin = Mpot.ncol = M.nlin;Mpot.nlin = Mpot.ncol = M.nlin;for (i = 1; i <= Mpot.nlin; i++) for (i = 1; i <= Mpot.nlin; i++)

for (j = 1; j <= Mpot.ncol; j++)for (j = 1; j <= Mpot.ncol; j++)Mpot.elem[i][j] = (i == j) ? 1 : 0;Mpot.elem[i][j] = (i == j) ? 1 : 0;

/* Calculo da matriz potencia/* Calculo da matriz potencia */*/

for (k = 1; k <= p; k++)for (k = 1; k <= p; k++)Mpot = MultMat (Mpot, M);Mpot = MultMat (Mpot, M);

/* Escrita da matriz potencia/* Escrita da matriz potencia */*/

printf ("\nMatriz potencia: \n\n");printf ("\nMatriz potencia: \n\n");EscreverMatriz (Mpot);EscreverMatriz (Mpot);

printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

Os argumentos e o valor retornado são estruturas

Page 60: Capítulo IX – Ponteiros

/*/* Funcao LerMatrizQuadrada: ler a matriz argumento pelo Funcao LerMatrizQuadrada: ler a matriz argumento pelo tecladoteclado */*/

void LerMatrizQuadrada (matriz *Mat){void LerMatrizQuadrada (matriz *Mat){int i, j, n;int i, j, n;printf ("\nDigite a dimensao da matriz: ");printf ("\nDigite a dimensao da matriz: ");scanf ("%d", &n);scanf ("%d", &n);while (n <= 0) {while (n <= 0) {

printf ("\tDimensao < 1; Digite novamente: ");printf ("\tDimensao < 1; Digite novamente: ");scanf ("%d", &n);scanf ("%d", &n);

}}(*Mat).ncol = (*Mat).nlin = n;(*Mat).ncol = (*Mat).nlin = n;for (i = 1; i <= (*Mat).nlin; i++) {for (i = 1; i <= (*Mat).nlin; i++) {

printf ("\tLinha %d: ", i);printf ("\tLinha %d: ", i);for (j = 1; j <= (*Mat).ncol; j++)for (j = 1; j <= (*Mat).ncol; j++)

scanf ("%d", &(*Mat).elem[i][j]);scanf ("%d", &(*Mat).elem[i][j]);}}

}}

Na função main:LerMatrizQuadrada (&M);

Mat é um ponteiro para estrutura

*Mat é uma estrutura

Page 61: Capítulo IX – Ponteiros

/*/* Funcao EscreverMatriz: escrever a matriz argumento no Funcao EscreverMatriz: escrever a matriz argumento no videovideo */*/

void EscreverMatriz (matriz Mat) {void EscreverMatriz (matriz Mat) {int i, j;int i, j;for (i = 1; i <= Mat.nlin; i++) {for (i = 1; i <= Mat.nlin; i++) {

for (j = 1; j <= Mat.ncol; j++)for (j = 1; j <= Mat.ncol; j++)printf ("%10d", Mat.elem[i][j]);printf ("%10d", Mat.elem[i][j]);

printf ("\n");printf ("\n");}}

}} Na função main:EscreverMatriz (M);EscreverMatriz (Mpot);

Page 62: Capítulo IX – Ponteiros

matriz MultMat (matriz M1, matriz M2) {matriz MultMat (matriz M1, matriz M2) {int i, j, k, aux; matriz M3;int i, j, k, aux; matriz M3;M3.nlin = M1.nlin; M3.ncol = M2.ncol;M3.nlin = M1.nlin; M3.ncol = M2.ncol;if (M1.ncol == M2.nlin) {if (M1.ncol == M2.nlin) {

for (i = 1; i <= M3.nlin; i++)for (i = 1; i <= M3.nlin; i++)for (j = 1; j <= M3.ncol; j++) {for (j = 1; j <= M3.ncol; j++) {

aux = 0;aux = 0;for (k = 1; k <= M1.ncol; k++)for (k = 1; k <= M1.ncol; k++)

aux += aux += M1.elem[i][k]*M2.elem[k]M1.elem[i][k]*M2.elem[k]

[j];[j]; M3.elem[i][j] = aux;M3.elem[i][j] = aux;

}}}}elseelse

for (i = 1; i <= M3.nlin; i++)for (i = 1; i <= M3.nlin; i++)for (j = 1; j <= M3.ncol; j++)for (j = 1; j <= M3.ncol; j++)

M3.elem[i][j] = 0;M3.elem[i][j] = 0;return M3;return M3;

}}

Na função main:Mpot = MultMat (Mpot, M);

Page 63: Capítulo IX – Ponteiros

9.4.4 – Recursividade com variáveis 9.4.4 – Recursividade com variáveis indexadas indexadas

Exemplo: formulação recursiva para a procura Exemplo: formulação recursiva para a procura bináriabinária

ProcBinaria (x, inf, sup, Vet) =ProcBinaria (x, inf, sup, Vet) =

FALSO se (x < Vet[inf] ou x > Vet[sup]) FALSO se (x < Vet[inf] ou x > Vet[sup]) VERDADE se (x == Vet[med]) VERDADE se (x == Vet[med]) ProcBinaria (x, inf, med-1, Vet) se (x < Vet[med]) ProcBinaria (x, inf, med-1, Vet) se (x < Vet[med]) ProcBinaria (x, med+1, sup, Vet) se (x > Vet[med])ProcBinaria (x, med+1, sup, Vet) se (x > Vet[med])

-50

-11

42

73

104

145

156

177

218

239

2410

3011

3212

3813

4514

5015

5316

Vet

medinf supx

Page 64: Capítulo IX – Ponteiros

- - - - -- - - - -typedef int *vetor;typedef int *vetor;- - - - -- - - - -logic ProcBinaria (int, int, int, vetor);logic ProcBinaria (int, int, int, vetor);

int main () {int main () {int - - - -, n, num; vetor A;int - - - -, n, num; vetor A;

logic estah; - - - - -logic estah; - - - - -

Alocacao, leitura e ordenacao do vetor AAlocacao, leitura e ordenacao do vetor A

estah = estah = ProcBinaria (num, 0, n-1, A);ProcBinaria (num, 0, n-1, A);- - - - -- - - - -

}}logic ProcBinaria (int x, int inf, int sup, vetor Vet) {logic ProcBinaria (int x, int inf, int sup, vetor Vet) {

int med; logic r;int med; logic r;

if (x < Vet[inf] || x > Vet[sup]) r = FALSE;if (x < Vet[inf] || x > Vet[sup]) r = FALSE; else {else {

med = (inf + sup) / 2;med = (inf + sup) / 2;if (x == Vet[med]) r = TRUE;if (x == Vet[med]) r = TRUE;else if (x < Vet[med]) else if (x < Vet[med]) r = ProcBinaria (x, inf, med-1, Vet);r = ProcBinaria (x, inf, med-1, Vet);else else r = ProcBinaria (x, med+1, sup, Vet);r = ProcBinaria (x, med+1, sup, Vet);

}} return r;return r;}}

A

Vet

A[0]

Os ponteiros Vet de todas as chamadas recursivas apontarão para A[0]

Page 65: Capítulo IX – Ponteiros

Exercícios 9.4:Exercícios 9.4:1.1. Um conjunto de números inteiros não repetidos pode ser Um conjunto de números inteiros não repetidos pode ser

representado por uma estrutura com dois campos: um representado por uma estrutura com dois campos: um vetor guardando seus elementos e um inteiro contendo o vetor guardando seus elementos e um inteiro contendo o número de elementos do conjuntonúmero de elementos do conjunto

Considerando como Considerando como UniversoUniverso o conjunto de números o conjunto de números inteiros no intervalo inteiros no intervalo [1 .. 20][1 .. 20], fazer:, fazer:

a)a) Uma função que tenha como parâmetro um conjunto e Uma função que tenha como parâmetro um conjunto e que retorne esse conjunto sem elementos repetidos e sem que retorne esse conjunto sem elementos repetidos e sem elementos que não pertençam ao referido universoelementos que não pertençam ao referido universo

b)b)Uma função que tenha dois conjuntos como parâmetros e Uma função que tenha dois conjuntos como parâmetros e que retorne o conjunto união desses conjuntosque retorne o conjunto união desses conjuntos

c)c) Uma função análoga à do item b, para o conjunto Uma função análoga à do item b, para o conjunto interseçãointerseção

Page 66: Capítulo IX – Ponteiros

d)d) Uma função que receba um conjunto como parâmetro e que Uma função que receba um conjunto como parâmetro e que retorne o seu conjunto complemento, em relação ao referido retorne o seu conjunto complemento, em relação ao referido universo.universo.

e)e) Uma função que receba um conjunto como parâmetro e que o Uma função que receba um conjunto como parâmetro e que o liste no seguinte formato: {elemento, elemento, . . . , liste no seguinte formato: {elemento, elemento, . . . , elemento}, ou, se for vazio, {conjunto vazio}elemento}, ou, se for vazio, {conjunto vazio}

f)f) Um programa principal que leia uma expressão contendo Um programa principal que leia uma expressão contendo vários conjuntos e vários operadores de conjuntos (vários conjuntos e vários operadores de conjuntos (UU = união, = união, II = interseção, = interseção, CC = complemento), que use a função do item a = complemento), que use a função do item a para limpá-la, exibindo-a em seguida, e que calcule e escreva o para limpá-la, exibindo-a em seguida, e que calcule e escreva o valor do conjunto resultado da expressão, usando as funções valor do conjunto resultado da expressão, usando as funções dos outros itensdos outros itens

Exemplo: se os dados de entrada forem:Exemplo: se os dados de entrada forem:{9 11 3 7 6 3} U {3 11 15 22 10 5 9} I {18 1 3 9 -5 14 7 5} C I {7 2 3 11 13 15}{9 11 3 7 6 3} U {3 11 15 22 10 5 9} I {18 1 3 9 -5 14 7 5} C I {7 2 3 11 13 15}

A saída deve ser do tipo:A saída deve ser do tipo:

{9 11 3 7 6} U {3 11 15 10 5 9} I {18 1 3 9 14 7 5} C I {7 2 3 11 13 15} = {9 11 3 7 6} U {3 11 15 10 5 9} I {18 1 3 9 14 7 5} C I {7 2 3 11 13 15} = {2 11 13 15}{2 11 13 15}

Page 67: Capítulo IX – Ponteiros

Capítulo IX – PonteirosCapítulo IX – Ponteiros

9.1 – Introdução9.1 – Introdução9.2 – Relação entre ponteiros e variáveis 9.2 – Relação entre ponteiros e variáveis

indexadasindexadas9.3 – Alocação dinâmica de memória9.3 – Alocação dinâmica de memória9.4 – Variáveis indexadas, ponteiros e 9.4 – Variáveis indexadas, ponteiros e

estruturas como parâmetros e elementos estruturas como parâmetros e elementos de retornode retorno

9.5 – Subprogramas como parâmetros9.5 – Subprogramas como parâmetros9.6 – Encadeamento de estruturas9.6 – Encadeamento de estruturas

Page 68: Capítulo IX – Ponteiros

9.5 – Subprogramas como 9.5 – Subprogramas como ParâmetrosParâmetros

Em C, o Em C, o nome de uma funçãonome de uma função é encarado pelo é encarado pelo compilador como sendo um compilador como sendo um ponteiro para o ponteiro para o códigocódigo dessa função dessa função

É uma É uma variávelvariável que guarda o que guarda o endereço da funçãoendereço da função na memória na memória

Esse fato possibilita, entre outras coisas, que Esse fato possibilita, entre outras coisas, que nomes de funçõesnomes de funções sejam passados como sejam passados como argumentosargumentos para outras funções para outras funções

Seja o programa da Seja o programa da Regra do TrapézioRegra do Trapézio visto no visto no Capítulo IICapítulo II

Page 69: Capítulo IX – Ponteiros

#include <stdio.h>#include <stdio.h>#include <math.h> #include <math.h> #include <stdlib.h> #include <stdlib.h> double f (double x) {return (log10(x) + 5);}double f (double x) {return (log10(x) + 5);}int main () {int main () {

long n, i; float a, b, p;long n, i; float a, b, p;double S1, S2, STrap, Dx;double S1, S2, STrap, Dx;scanf ("%f%f%f", &a, &b, &p);scanf ("%f%f%f", &a, &b, &p);S2 = 0; n = 5;S2 = 0; n = 5;do {do {

S1 = S2; n = 2*n;S1 = S2; n = 2*n;Dx = (b-a)/n; S2 = 0; i = 1;Dx = (b-a)/n; S2 = 0; i = 1;while (i <= n) {while (i <= n) {

STrap = Dx * (f(a+(i-1)*Dx) + f(a+i*Dx)) / 2;STrap = Dx * (f(a+(i-1)*Dx) + f(a+i*Dx)) / 2;S2 = S2 + STrap;S2 = S2 + STrap;i = i + 1;i = i + 1;

}}} while (fabs (S1-S2) > p);} while (fabs (S1-S2) > p);printf ("\nA Integral de f(x) no intervalo [%g, %g]", a, b);printf ("\nA Integral de f(x) no intervalo [%g, %g]", a, b);printf (" com precisao %g eh %g", p, S2);printf (" com precisao %g eh %g", p, S2);printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;

}}

Este programa calcula a integral de uma só função:

log10x + 5Pode-se fazer uma função integradora em que um dos parâmetros é o nome da função a ser integrada

Page 70: Capítulo IX – Ponteiros

#include<stdio.h>#include<stdio.h>#include<stdlib.h>#include<stdlib.h>#include<math.h>#include<math.h>

/* Declaracoes das 3 funcoes a serem integradas:/* Declaracoes das 3 funcoes a serem integradas:log10(x) + 5, x^3 - x, sen(x) + 2 log10(x) + 5, x^3 - x, sen(x) + 2 */*/

double f1 (double x) {double f1 (double x) {return (log10(x)+5);return (log10(x)+5);

}}double f2 (double x) {double f2 (double x) {

return (pow(x,3)-x);return (pow(x,3)-x);}}double f3 (double x) {double f3 (double x) {

return (sin(x)+2);return (sin(x)+2);}}

Page 71: Capítulo IX – Ponteiros

/*/* Declaracao da funcao integradoraDeclaracao da funcao integradora */*/

double integral (double f (double),float a, float b, double integral (double f (double),float a, float b, float p) {float p) {

double s1, s2, si, dx;double s1, s2, si, dx;int n, i;int n, i;

s2 = 0; n = 5;s2 = 0; n = 5;do {do {

s1 = s2; n = 2*n;s1 = s2; n = 2*n;dx = (b-a)/n; s2 = 0;dx = (b-a)/n; s2 = 0;for (i = 1 ; i <= n; i = i+1) {for (i = 1 ; i <= n; i = i+1) {

si = dx * (f(a+(i-1)*dx)+f(a+i*dx)) / 2;si = dx * (f(a+(i-1)*dx)+f(a+i*dx)) / 2;s2 = s2 + si;s2 = s2 + si;

}}} while (fabs(s1 - s2) >= p);} while (fabs(s1 - s2) >= p);return s2;return s2;

}}

A função f será substituída por aquela que vier como argumento

Page 72: Capítulo IX – Ponteiros

int main () {int main () {float a, b, p;float a, b, p;printf ("Integral de log10(x):\n\n\tlimite inferior: ");printf ("Integral de log10(x):\n\n\tlimite inferior: ");scanf ("%f", &a);scanf ("%f", &a);printf ("\tlimite superior: "); scanf ("%f", &b);printf ("\tlimite superior: "); scanf ("%f", &b);printf ("\tprecisao: ");scanf ("%f", &p);printf ("\tprecisao: ");scanf ("%f", &p);printf ("\n\tValor da integral: %lf\n\n",printf ("\n\tValor da integral: %lf\n\n",

integral (f1, a, b, p));integral (f1, a, b, p));printf ("Integral de x**3 - x:\n\n\tlimite inferior: ");printf ("Integral de x**3 - x:\n\n\tlimite inferior: ");scanf ("%f", &a);scanf ("%f", &a);printf ("\tlimite superior: "); scanf ("%f", &b);printf ("\tlimite superior: "); scanf ("%f", &b);printf ("\tprecisao: ");scanf ("%f", &p);printf ("\tprecisao: ");scanf ("%f", &p);printf ("\n\tValor da integral: %lf\n\n",printf ("\n\tValor da integral: %lf\n\n",

integral (f2, a, b, p));integral (f2, a, b, p));printf ("Integral de sen(x)+2:\n\n\tlimite inferior: ");printf ("Integral de sen(x)+2:\n\n\tlimite inferior: ");scanf ("%f", &a);scanf ("%f", &a);printf ("\tlimite superior: "); scanf ("%f", &b);printf ("\tlimite superior: "); scanf ("%f", &b);printf ("\tprecisao: ");scanf ("%f", &p);printf ("\tprecisao: ");scanf ("%f", &p);printf ("\n\tValor da integral: %lf\n\n",printf ("\n\tValor da integral: %lf\n\n",

integral (f3, a, b, p));integral (f3, a, b, p)); printf ("\n\n"); system ("pause"); return 0;printf ("\n\n"); system ("pause"); return 0;}}

Page 73: Capítulo IX – Ponteiros

Integral de log10(x):Integral de log10(x):

limite inferior: 1limite inferior: 1 limite superior: 20limite superior: 20 precisao: 0.0001precisao: 0.0001

Valor da integral: 112.768974Valor da integral: 112.768974

Integral de x**3 - x:Integral de x**3 - x:

limite inferior: 3limite inferior: 3 limite superior: 20limite superior: 20 precisao: 0.001precisao: 0.001

Valor da integral: 39784.250269Valor da integral: 39784.250269

Integral de sen(x)+2:Integral de sen(x)+2:

limite inferior: 0limite inferior: 0 limite superior: 6.28limite superior: 6.28 precisao: 0.00001precisao: 0.00001

Valor da integral: 12.560005Valor da integral: 12.560005

Resultado de uma execução

Page 74: Capítulo IX – Ponteiros

Subprogramas como parâmetrosSubprogramas como parâmetros são usados são usados em problemas em problemas científicoscientíficos envolvendo envolvendo funçõesfunções: :

Tabelas, gráficos, máximos e mínimos, Tabelas, gráficos, máximos e mínimos, equações diferenciais, etc.equações diferenciais, etc.

Page 75: Capítulo IX – Ponteiros

Exercícios 9.5:Exercícios 9.5:1.1. Fazer uma função para imprimir tabelas de funções de Fazer uma função para imprimir tabelas de funções de

uma variável. Seus parâmetros devem ser: A função uma variável. Seus parâmetros devem ser: A função f(x)f(x) cuja tabela deve ser impressa, os extremos cuja tabela deve ser impressa, os extremos a a e e bb do intervalo a ser impresso e uma variável inteira do intervalo a ser impresso e uma variável inteira nn contendo o número desejado de linhas da tabela.contendo o número desejado de linhas da tabela.

Cada linha da tabela deve conter um valor de Cada linha da tabela deve conter um valor de xx e o e o correspondente valor de correspondente valor de f(x)f(x). O primeiro valor de . O primeiro valor de xx da da tabela deve ser o valor de tabela deve ser o valor de aa e o último deve ser o valor e o último deve ser o valor de de bb. O número total de linhas deve ser o valor de . O número total de linhas deve ser o valor de nn..

Fazer um programa que chame a referida função para Fazer um programa que chame a referida função para imprimir tabelas para as seguintes funções:imprimir tabelas para as seguintes funções:

Os intervalos e o número de linhas de cada tabela devem ser lidos. As três funções acima devem ser também programadas

Page 76: Capítulo IX – Ponteiros

2.2. Fazer uma função para traçar gráficos de funções de Fazer uma função para traçar gráficos de funções de uma variável no modo gráfico do vídeo do uma variável no modo gráfico do vídeo do computador. Seus parâmetros devem ser a função computador. Seus parâmetros devem ser a função f(x)f(x) cujo gráfico deve ser desenhado e os extremos cujo gráfico deve ser desenhado e os extremos a a e e bb do intervalo de variação de do intervalo de variação de x x nesse gráfico.nesse gráfico.

O gráfico deve ocupar a tela inteira, portanto a O gráfico deve ocupar a tela inteira, portanto a variação da abscissa deve ser ajustar ao tamanho do variação da abscissa deve ser ajustar ao tamanho do intervalointervalo

Fazer um programa que chame a referida função para Fazer um programa que chame a referida função para desenhar gráficos para as seguintes funções:desenhar gráficos para as seguintes funções:

Nesse programa, os intervalos devem ser lidos

Page 77: Capítulo IX – Ponteiros

Capítulo IX – PonteirosCapítulo IX – Ponteiros

9.1 – Introdução9.1 – Introdução9.2 – Relação entre ponteiros e variáveis 9.2 – Relação entre ponteiros e variáveis

indexadasindexadas9.3 – Alocação dinâmica de memória9.3 – Alocação dinâmica de memória9.4 – Variáveis indexadas, ponteiros e 9.4 – Variáveis indexadas, ponteiros e

estruturas como parâmetros e elementos estruturas como parâmetros e elementos de retornode retorno

9.5 – Subprogramas como parâmetros9.5 – Subprogramas como parâmetros9.6 – Encadeamento de estruturas9.6 – Encadeamento de estruturas

Page 78: Capítulo IX – Ponteiros

9.6 – Encadeamento de 9.6 – Encadeamento de EstruturasEstruturas

EstruturasEstruturas também podem ser também podem ser alocadas alocadas dinamicamentedinamicamente

Por exemplo, sejam as seguintes declarações:Por exemplo, sejam as seguintes declarações:

typedef struct st st;typedef struct st st;struct st {int a; float b;};struct st {int a; float b;};st *p;st *p;

O comando O comando

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));

aloca espaço aloca espaço para uma estrutura para uma estrutura stst, cujo , cujo endereçoendereço é atribuído à variável é atribuído à variável pp

Page 79: Capítulo IX – Ponteiros

typedef struct st st;typedef struct st st; struct st {int a; float b;};struct st {int a; float b;}; st *p;st *p;p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));

Representação gráfica:Representação gráfica:

Os Os parêntesisparêntesis são necessários pois são necessários pois ‘.’‘.’ tem tem precedência sobre precedência sobre ‘*’‘*’

Outra forma de referenciar os Outra forma de referenciar os camposcampos de uma de uma estrutura apontadaestrutura apontada::

a bp

Atribuindo:

(*p).a = 5;(*p).b = 17.3;

5 17.3

(*p).a = 5;(*p).b = 17.3;

p->a = 5;p->b = 17.3;

equivalem a

(*p) é uma estrutura sem nome

Page 80: Capítulo IX – Ponteiros

Exemplo:Exemplo: sejam as seguintes declarações: sejam as seguintes declarações:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

e os seguintes comandos:e os seguintes comandos:

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p; q != NULL; q = q->prox)for (q = p; q != NULL; q = q->prox)

printf ("%4d", q->a);printf ("%4d", q->a);

Um dos campos da estrutura st é um ponteiro para uma estrutura de mesmo tipo (st)

Page 81: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p; q != NULL; q = q->prox)for (q = p; q != NULL; q = q->prox)

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

Formou-se um encadeamento de estruturas

Page 82: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (for (q = p; q = p; q != NULL; q = q->prox)q != NULL; q = q->prox)

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

q

Page 83: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q = q->prox)q != NULL; q = q->prox)

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

q

2Vídeo

Page 84: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q != NULL; q = q->proxq = q->prox))

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

q

2Vídeo

q

Page 85: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q = q->prox)q != NULL; q = q->prox)

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

2Vídeo

q

Page 86: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q = q->prox)q != NULL; q = q->prox)

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

2 3Vídeo

q

Page 87: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q != NULL; q = q->proxq = q->prox))

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

2 3Vídeo

q q

Page 88: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q = q->prox)q != NULL; q = q->prox)

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

2 3Vídeo

q

Page 89: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q = q->prox)q != NULL; q = q->prox)

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

2 3 5Vídeo

q

Page 90: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q != NULL; q = q->proxq = q->prox))

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

2 3 5Vídeo

q q

q == NULL:Fim!!!

O ponteiro q percorreu o encadeamento com o comando

q = q->prox

Page 91: Capítulo IX – Ponteiros

Seja a execução dos comandos:Seja a execução dos comandos:

typedef struct st st;typedef struct st st;struct st {int a; st *prox;}; struct st {int a; st *prox;}; st *p, *q;st *p, *q;

p = (st *) malloc (sizeof(st));p = (st *) malloc (sizeof(st));p->a = 2;p->a = 2;p->prox = (st *) malloc (sizeof(st));p->prox = (st *) malloc (sizeof(st));p->prox->a = 3;p->prox->a = 3;p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox = (st *) malloc (sizeof(st));p->prox->prox->a = 5;p->prox->prox->a = 5;p->prox->prox->prox = NULL;p->prox->prox->prox = NULL;for (q = p;for (q = p; q != NULL; q != NULL; q = q->proxq = q->prox))

printf ("%4d", q->a);printf ("%4d", q->a);

pa prox2

a prox3

a prox5

q

A constante NULL é muito usada para teste de final de percurso

O ponteiro q percorreu o encadeamento com o comando

q = q->prox

Page 92: Capítulo IX – Ponteiros

pa prox2

a prox3

a prox5

q

Duas formas de referenciar este local

p->prox->prox->a

(*(*(*p).prox).prox).a

Qual delas é mais cômoda???

Page 93: Capítulo IX – Ponteiros

Encadeamento de estruturasEncadeamento de estruturas é a principal razão é a principal razão para incorporação de para incorporação de variáveis-ponteirosvariáveis-ponteiros nas nas linguagens de programaçãolinguagens de programação

A disciplina A disciplina CES-11 Algoritmos e Estruturas de CES-11 Algoritmos e Estruturas de DadosDados mostra a grande mostra a grande variedadevariedade de alternativas de alternativas de armazenamento de informações oferecida por de armazenamento de informações oferecida por encadeamentos desse gênero encadeamentos desse gênero

Modelos como Modelos como listas lineareslistas lineares, , árvoresárvores, , grafosgrafos, , estruturas multi-ligadasestruturas multi-ligadas muito se beneficiam da muito se beneficiam da inclusão de um ou mais ponteiros em variáveis do inclusão de um ou mais ponteiros em variáveis do tipo tipo structstruct. .

O último capítulo, O último capítulo, Noções de Estruturas de Noções de Estruturas de DadosDados, oferece uma pequena amostra da utilidade , oferece uma pequena amostra da utilidade desses modelosdesses modelos

Page 94: Capítulo IX – Ponteiros

No exemplo anterior, a No exemplo anterior, a estruturaestrutura tinha apenas tinha apenas um um campo-ponteirocampo-ponteiro

Estruturas com Estruturas com mais campos-ponteirosmais campos-ponteiros permitem construções bem mais permitem construções bem mais complexas complexas

Exemplo: Exemplo: sejam as declarações:sejam as declarações:

typedef struct celula celula;typedef struct celula celula;typedef struct celula *noh;typedef struct celula *noh;struct celula {struct celula {informacao info; noh pai, fesq, idir;informacao info; noh pai, fesq, idir;

};};

Elas possibilitam construções de Elas possibilitam construções de árvores árvores (próximo slide)(próximo slide)

info paifesq idir

Célula

Page 95: Capítulo IX – Ponteiros

info paifesq idir

Célula

Aplicações:

Organogramas

Resolução de expressões aritméticas

Jogos eliminatórios de um campeonato

etc.