Você está na página 1de 35

ESTRUTURA DE DADOS

Ricardo de Almeida (ricalme@hotmail.com)

Agenda
1. 2. 3. 4. 5. 6. 7.

Relembrando... Matrizes Dinmicas Matriz representada por Vetor Simples Matriz representada por Vetor de Ponteiros Operaes com Matrizes Exerccios de Fixao Reviso

Relembrando...
Quais pontos foram vistos na aula anterior? Alocao Esttica x Alocao Dinmica. Matrizes. Passagem de Matrizes para Funes.

Matrizes Dinmicas
Matrizes Dinmicas As matrizes declaradas estaticamente sofrem das mesmas

limitaes dos vetores: precisamos saber de antemo suas dimenses. Se as dimenses s so conhecidas em tempo de

execuo, devemos utilizar alocao dinmica. O problema que


encontramos que a linguagem C s permite alocarmos dinamicamente conjuntos unidimensionais. Para trabalharmos com matrizes alocadas dinamicamente, temos que criar abstraes conceituais com vetores para representar conjuntos estratgias bidimensionais. distintas para Nesta seo, discutiremos matrizes duas representar alocadas

dinamicamente.

Matrizes Dinmicas
Matriz representada por Vetor Simples Concretamente, para representar uma matriz, precisamos de um espao de memria suficiente para armazenar seus elementos.

Podemos ento adotar a estratgia de armazenar os elementos de


uma matriz num vetor simples. Assim, reservamos as primeiras posies do vetor para armazenar os elementos da primeira linha, seguidos dos elementos da segunda linha, e assim por diante. Conceitualmente, trabalharemos com um conjunto bidimensional, mas, de fato, trabalharemos com um vetor unidimensional. Para tal estratgia temos que criar uma disciplina para acessar os elementos da matriz, representada conceitualmente.

Matrizes Dinmicas
Matriz representada por Vetor Simples A estratgia de endereamento para acessar os elementos a seguinte: se quisermos acessar o que seria o elemento mat[i][j] de uma matriz, devemos acessar o elemento v[k], com

k = i*n+j, onde n representa o nmero de colunas da matriz.

Matrizes Dinmicas
Matriz representada por Vetor Simples Esta conta de endereamento intuitiva: para acessarmos os elementos da terceira (i=2) linha da matriz, temos que pular duas linhas de elementos (i*n) e, indexar o elemento da linha com j. Com esta estratgia, a alocao da matriz recai numa alocao de vetor que tem m*n elementos, onde m e n representam as dimenses da matriz.
float *mat; /* matriz m x n representada por um vetor */ ... mat = (float*) malloc(m*n*sizeof(float));

No entanto, somos obrigados a usar uma notao desconfortvel, v[i*n+j], para acessar os elementos, o que pode deixar o cdigo pouco legvel.

Matrizes Dinmicas
Matriz representada por Vetor de Ponteiros Vamos agora apresentar outra estratgia para trabalhar com matrizes dinmicas que usam vetores de ponteiros. Nesta segunda estratgia, cada linha da matriz representada por um

vetor independente.
A matriz ento representada por um vetor de vetores, ou vetor de ponteiros, no qual cada elemento armazena o endereo do primeiro elemento de cada linha.

Matrizes Dinmicas
Matriz representada por Vetor de Ponteiros A figura abaixo ilustra o arranjo da memria utilizada nesta estratgia:

Matrizes Dinmicas
Matriz representada por Vetor de Ponteiros A alocao da matriz agora mais elaborada. Primeiro, temos que alocar o vetor de ponteiros. Em seguida, alocamos cada uma das linhas da matriz, atribuindo seus endereos aos elementos do

vetor de ponteiros criado.


O cdigo abaixo ilustra esta codificao:
int i; float **mat; /* matriz representada por um vetor de ponteiros */ ...

mat = (float**) malloc(m*sizeof(float*));


for (i=0; i<m; i++) m[i] = (float*) malloc(n*sizeof(float));

Matrizes Dinmicas
Matriz representada por Vetor de Ponteiros A grande vantagem desta estratgia que o acesso aos elementos feito da mesma forma que quando temos uma matriz criada estaticamente, pois, se mat representa uma matriz alocada

segundo esta estratgia, mat[i] representa o ponteiro para o


primeiro elemento da linha i, e, conseqentemente, mat[i][j] acessa o elemento da coluna j da linha i. A liberao do espao de memria ocupado pela matriz tambm exige a construo de um lao, pois temos que liberar cada linha antes de liberar o vetor de ponteiros:
... for (i=0; i<m; i++) free(mat[i]); free(mat);

Operaes com Matrizes


Operaes com Matrizes Para exemplificar o uso de matrizes sobre as dinmicas, quais vamos podemos

implementar

funes

bsicas,

futuramente implementar funes mais complexas:

cria: operao que cria uma matriz de dimenso m por n;


libera: operao que libera a memria alocada para a matriz. atribui: operao que atribui o elemento da linha i e da coluna j da matriz. apresenta: operao que apresenta os elementos da matriz desejada. A seguir, mostraremos a implementao dessas operaes usando as duas estratgias para alocar dinamicamente uma matriz, apresentadas na seo anterior.

Operaes com Matrizes


Exemplo 6.4: Criar as funes cria_matriz, libera_matriz, atribui_matriz, apresenta_matriz, usando Vetor Simples.
#include <stdio.h> #include <stdlib.h> /* Exemplo 6.4 - Operaes usando Vetor Simples */ /* Funo para alocar o vetor da Matriz lin x col */ float * cria_matriz (int plin, int pcol) { float *v; int i; /* Verifica os parmetros recebidos */ if (plin < 1 || pcol < 1) { printf ("** Erro: Parametro invalido **\n"); system("PAUSE"); exit (1); }

Operaes com Matrizes


/* Aloca o vetor da Matriz */ // v = (float *) malloc (plin * pcol * sizeof(float *)); v = (float *) calloc (plin * pcol, sizeof(float *)); if (v == NULL) { printf ("** Erro: Memoria Insuficiente **"); system("PAUSE"); exit (1); } return (v); /* Retorna o ponteiro do vetor da Matriz */ } /* Funo para desalocar o vetor da Matriz */ //void * libera_matriz (float *pv) /* funcionaria assim ??? */ float * libera_matriz (float *pv) { /* Caso a matriz esteja vazia, no desaloca nada */ if (pv == NULL) return (NULL); /* Desaloca o vetor da Matriz */ free (pv); return (pv); /* Retorna o ponteiro do vetor da Matriz */

Operaes com Matrizes


/* Funo para apresentar a Matriz lin x col */ void apresenta_matriz (int plin, int pcol, float *pv) { int i, j; /* Verifica os parmetros recebidos */ if (plin < 1 || pcol < 1) { printf ("** Erro: Parametro invalido **\n"); system("PAUSE"); exit (1); } /* Apresenta os Valores Iniciais da Matriz */ for (i=0; i<plin; i++) { printf ("|"); for (j=0; j<pcol; j++) { printf (" %.2f ", pv [i*pcol+j]); if (j == pcol-1) printf ("|"); } printf ("\n"); } printf ("\n");

Operaes com Matrizes


/* Funo para solicitar/atribuir as Notas dos Alunos */ void atribui_matriz (int pa, int pn, float *pv) { int i, j; for (i=0; i<pa; i++) { for (j=0; j<pn; j++) { printf ("Digite a Nota %d, do Aluno %d: ", j+1, i+1); scanf ("%f", &pv[i*pn+j]); } printf ("\n"); }

/* Verificar os valores gravados */ for (i=0; i<pa; i++) for (j=0; j<pn; j++) printf ("A Nota %d, do Aluno %d eh: %.2f \n", j+1, i+1, pv[i*pn+j]); printf ("\n");

Operaes com Matrizes


/* Funo para Calcular a Mdia das Notas de um Aluno */ void calcula_media (int pa, int pn, float *pv) { int i, j; float media; for (i=0; i<pa; i++) { /* Calcula a Mdia dos respectivos Alunos */ media = 0.0; for (j=0; j<pn; j++) { media = media + pv [i*pn+j]; } media = media / pn; /* Apresenta a Mdia dos respectivos Alunos */ printf ("A Media do Aluno %d eh: %.2f \n", i+1, media);

} printf ("\n");

Operaes com Matrizes


/* Incio do Programa Principal */ int main (void) { int a, n, i, j; float *mat; /* matriz a ser alocada */ /* Solicita o nmero de Alunos */ printf ("Informe o numero de alunos: "); scanf ("%d", &a); /* Solicita o nmero de Notas */ printf ("Informe o numero de notas: "); scanf ("%d", &n); printf ("\n"); /* Cria uma Matriz lin x col de Forma Dinmica */ mat = cria_matriz(a, n); /* Apresenta os Valores Iniciais da Matriz */ apresenta_matriz(a, n, mat); /* Leitura das Notas */ atribui_matriz(a, n, mat);

Operaes com Matrizes


/* Apresenta os Valores Iniciais da Matriz */ apresenta_matriz(a, n, mat);

/* Calcula as Mdias dos Alunos */ calcula_media(a, n, mat);


/* Desalocar a Matriz lin x col */ mat = libera_matriz(mat); /* Apresenta os Valores Finais da Matriz */ apresenta_matriz(a, n, mat); system("PAUSE"); return (0);

Operaes com Matrizes


Exemplo 6.5: Criar as funes cria_matriz, libera_matriz, atribui_matriz, apresenta_matriz, usando Vetor de Ponteiros.
#include <stdio.h> #include <stdlib.h> /* Exemplo 6.5 - Operaes usando Vetor de Ponteiros /* /* Funo para alocar a Matriz lin x col */ float ** cria_matriz (int plin, int pcol) { float **v; int i; /* Verifica os parmetros recebidos */ if (plin < 1 || pcol < 1) { printf ("** Erro: Parametro invalido **\n"); system("PAUSE"); exit (1); }

Operaes com Matrizes


/* Aloca as linhas da Matriz */ // v = (float **) malloc (plin * sizeof(float *)); v = (float **) calloc (plin, sizeof(float *)); if (v == NULL) { printf ("** Erro: Memoria Insuficiente **"); system("PAUSE"); exit (1); } /* Aloca as colunas da Matriz */ for (i=0; i<plin; i++) { // v[i] = (float*) malloc (pcol * sizeof(float)); v[i] = (float*) calloc (pcol, sizeof(float)); if (v == NULL) { printf ("** Erro: Memoria Insuficiente **"); system("PAUSE"); exit (1); } /* Retorna o ponteiro para a Matriz */

} return (v);

Operaes com Matrizes


/* Funo para desalocar a Matriz lin x col */ float ** libera_matriz (int plin, int pcol, float **pv) { int i; /* Caso a matriz esteja vazia, no desaloca nada */ if (pv == NULL) return (NULL); if (plin < 1 || pcol < 1) { printf ("** Erro: Parametro invalido **\n"); system("PAUSE"); exit (1); } /* Desaloca as linhas da Matriz */ for (i=0; i<plin; i++) free (pv[i]); free (pv); } return (pv); /* Retorna o ponteiro para a Matriz */

Operaes com Matrizes


/* Funo para apresentar a Matriz lin x col */ void apresenta_matriz (int plin, int pcol, float **pv) { int i, j; /* Verifica os parmetros recebidos */ if (plin < 1 || pcol < 1) { printf ("** Erro: Parametro invalido **\n"); system("PAUSE"); exit (1); } /* Apresenta os Valores Iniciais da Matriz */ for (i=0; i<plin; i++) { printf ("|"); for (j=0; j<pcol; j++) { printf (" %.2f ", pv [i][j]); if (j == pcol-1) printf ("|"); } printf ("\n"); } printf ("\n"); }

Operaes com Matrizes


/* Funo para solicitar/atribuir as Notas dos Alunos */ void atribui_matriz (int pa, int pn, float **pv) { int i, j; for (i=0; i<pa; i++) { for (j=0; j<pn; j++) { printf ("Digite a Nota %d, do Aluno %d: ", j+1, i+1); scanf ("%f", &pv[i][j]); } printf ("\n"); }

/* Verificar os valores gravados */ for (i=0; i<pa; i++) for (j=0; j<pn; j++) printf ("A Nota %d, do Aluno %d eh: %.2f \n", j+1, i+1, pv[i][j]); printf ("\n");

Operaes com Matrizes


/* Funo para calcular a Mdia das Notas de um Aluno */ void calcula_media (int pa, int pn, float **pv) { int i, j; float media; for (i=0; i<pa; i++) { /* Calcula a Mdia dos respectivos Alunos */ media = 0.0; for (j=0; j<pn; j++) { media = media + pv [i][j]; } media = media / pn; /* Apresenta a Mdia dos respectivos Alunos */ printf ("A Media do Aluno %d eh: %.2f \n", i+1, media);

} printf ("\n");

Operaes com Matrizes


/* Incio do Programa Principal */ int main (void) { int a, n, i, j; float **mat; /* matriz a ser alocada */ /* Solicita o nmero de Alunos */ printf ("Informe o numero de alunos: "); scanf ("%d", &a); /* Solicita o nmero de Notas */ printf ("Informe o numero de notas: "); scanf ("%d", &n); printf ("\n"); /* Cria uma Matriz lin x col de Forma Dinmica */ mat = cria_matriz(a, n); /* Apresenta os Valores Iniciais da Matriz */ apresenta_matriz(a, n, mat); /* Leitura das Notas */ atribui_matriz(a, n, mat);

Operaes com Matrizes


/* Apresenta os Valores Iniciais da Matriz */ apresenta_matriz(a, n, mat);

/* Calcula as Mdias dos Alunos */ calcula_media(a, n, mat);


/* Desalocar a Matriz lin x col */ mat = libera_matriz(a, n, mat); /* Apresenta os Valores Finais da Matriz */ apresenta_matriz(a, n, mat); system("PAUSE"); return (0);

Exerccios Prticos de Fixao

Exerccios Prticos de Fixao


1 Incremente o exemplo 6.4, incluindo uma funo que possa incluir um novo aluno e suas notas; arrumar a lgica para que aps calcular a mdia

dos alunos, esta nota seja gravada como mais um valor na matriz:
a) Como sugesto utilize uma funo do tipo redimensiona_matriz para as duas alteraes, podendo aumentar a linha ou a coluna. 2 - Incremente o exemplo 6.5, incluindo uma funo que possa incluir um novo aluno e suas notas; arrumar a lgica para que aps calcular a mdia dos alunos, esta nota seja gravada como mais um valor na matriz: a) Como sugesto utilize uma funo do tipo redimensiona_matriz para as duas alteraes, podendo aumentar a linha ou a coluna. 3 - Apresente uma soluo e/ou explicao para o problema da liberao

da matriz, aproveite para increment-la nos exerccios 1 e 2 acima.

Matrizes
E como seria para trabalharmos com Caracteres? o que veremos no prximo captulo, quando discutirmos: Cadeia de Caracteres; Funes de Manipulao;

Reviso
Quais pontos foram vistos neste captulo? Alocao Esttica x Alocao Dinmica. Matrizes. Passagem de Matrizes para Funes. Matriz representada por Vetor Simples Matriz representada por Vetor de Ponteiros Operaes com Matrizes.

Reviso
Matriz: Matriz representada por vetor bidimensional esttico: elementos acessados com indexao dupla m[ i ][ j ]. Matriz representada por um vetor simples: conjunto bidimensional representado em vetor unidimensional. Matriz representada por um vetor de ponteiros: cada elemento do vetor armazena o endereo do primeiro elemento de cada linha da matriz. Funes para gerncia de memria: realloc permite re-alocar um vetor preservando o contedo dos elementos, que permanecem vlidos aps a re-alocao

Reviso
Matriz: Matriz mat com n colunas representada no vetor v, alocado dinamicamente mat[i][j] como em v[ i * n + j ].
/* exemplo: matriz com m linhas e n colunas */ float *v; /* matriz m x n representada por um vetor */ ...

v = (float*) malloc(m*n*sizeof(float)); oc(m*sizeof(float*));

Reviso
Matriz: Matriz mat representada atravs de vetor de ponteiros, alocado dinamicamente.
/* exemplo: matriz com m linhas e n colunas */ float** mat; ... mat = (float**) malloc(m*sizeof(float*)); for (i=0; i<m; i++) mat[i] = (float*) malloc(n*sizeof(float)); /* exemplo: passagem de matriz para funo */ float acessa (int m, int n, float** mat, int i, int j)

ESTRUTURA DE DADOS

Ricardo de Almeida (ricalme@hotmail.com)