Computadores Digitais 2
Prof. Rodrigo de Souza Couto
Linguagens de Programação – DEL-Poli/UFRJ
Prof. Miguel Campista
Aula de Hoje
• Matrizes
– Alocação estática versus dinâmica
– Vetores bidimensionais – matrizes
– Matrizes dinâmicas
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
ATENÇÃO
• Esta apresentação foi baseada nos seguinte trabalhos:
– Notas de aula do Prof. Marco Casanova da PUC-Rio
• http://www.inf.puc-rio.br/~inf1620/material.html
– Waldemar Celes, Renato Cerqueira, José Lucas Rangel,
“Introdução a Estruturas de Dados”, Editora Campus,
2004
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Parte 1
Programação (linguagem C)
Matrizes
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Alocação Estática versus
Dinâmica
• Alocação estática de vetor
– É necessário saber de antemão a dimensão máxima do
vetor
– Variável que representa o vetor armazena endereço
ocupado pelo primeiro elemento do vetor
– Vetor declarado dentro do corpo de uma função não
pode ser usado fora do corpo da função
#define N 10
int v[N]
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Alocação Estática versus
Dinâmica
• Alocação dinâmica de vetor
– Dimensão do vetor pode ser definida em tempo de
execução
– Variável do tipo ponteiro recebe o valor do endereço do
primeiro elemento do vetor
– Área de memória ocupada pelo vetor permanece válida
até que seja explicitamente liberada (função free)
• Vetor alocado dentro do corpo de uma função pode ser
usado fora do corpo da função, enquanto estiver alocado
int v;
...
v = (int*) malloc(n*sizeof(int))
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Alocação Estática versus
Dinâmica
• Função realloc
– Permite realocar um vetor preservando o conteúdo dos
elementos, que permanecem válidos após a realocação
– Exemplo
• m representa a nova dimensão do vetor
int v;
...
v = (int*) malloc(n*sizeof(int))
v = (int*) realloc(v,m*sizeof(int))
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Vetores Bidimensionais:
Matrizes
• Vetor bidimensional (ou matriz)
– Elementos armazenados de forma contínua
• Linha a linha
– Alocação Estática
124
int m[3][2] = {{1,2},{3,4},{5,6}}
m[i][j]
i
j
1
2
3
4
5
6
Computadores Digitais II– DETEL-FEN/UERJ
m
6
120
5
116
4
3
112
2
104
1
100
108
Prof. Rodrigo de Souza Couto
Vetores Bidimensionais:
Matrizes
• Vetor bidimensional (ou matriz)
– Elementos armazenados de forma contínua
• Linha a linha
– Alocação Estática
124
int m[3][2] = {{1,2},{3,4},{5,6}}
m[i][j]
i
j
1
2
3
4
5
6
Primeiro elemento: m[0]0]
Último elemento: m[2][1]
Computadores Digitais II– DETEL-FEN/UERJ
m
6
120
5
116
4
3
112
2
104
1
100
108
Prof. Rodrigo de Souza Couto
Vetores Bidimensionais:
Matrizes
• Variável m do exemplo representa um ponteiro para o
primeiro “vetor-linha”
– m[1] é um ponteiro para o segundo “vetor-linha”
– m[2] é um ponteiro para o terceiro “vetor-linha”
124
int m[3][2] = {{1,2},{3,4},{5,6}}
6
120
m[2]
5
116
112
m[1]
4
3
2
104
1
100
m
Computadores Digitais II– DETEL-FEN/UERJ
108
Prof. Rodrigo de Souza Couto
Vetores Bidimensionais:
Matrizes
• Outra Formas de inicialização
– Explícita
int m[3][2] = {{1,2},{3,4},{5,6}}
– Sequencial
int m[3][2] = {1,2,3,4,5,6}
– Omissão do número de linhas
• Número de colunas sempre é obrigatório
int m[][2] = {1,2,3,4,5,6}
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Passagem de Matrizes para
Funções
• Declaração na função principal
float m[4][3];
• Parâmetro declarado como “vetor-linha”
void (...,float (*m)[3],...);
• Parâmetro declarado como matriz
void (...,float m[][3],...);
Primeira dimensão pode ser
sempre omitida
Matriz pode ser modificada
pela função
• Dentro da função a matriz é acessada com a
indexação dupla normal de matrizes
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Mais Dimensões
• Exemplo de Declaração
int m[3][2][4][4][3];
• Exemplo de Passagem para função
void (...,int m[][2][4][4][3],...);
Compilador pode definir
limites para dimensões
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Matrizes Dinâmicas
• Assim, como no caso de vetores, às vezes as
dimensões das matrizes são conhecidas apenas em
tempo de execução
• Em C, apenas vetores podem ser alocados
dinamicamente
Como posso alocar matrizes
dinamicamente ?
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Matrizes Dinâmicas
• Soluções
– Matriz com vetor simples
• Ex: Matriz 2x2
– 2 primeiros elementos do vetor -> linha 1
– 2 últimos elementos do vetor -> linha 2
1
2
3
4
1
2 3
4
– Matriz com vetor de ponteiros
• Cada elemento do vetor é um ponteiro para outro vetor
– Cada vetor apontado é uma linha
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Matrizes Dinâmicas com
Vetor Simples
• Matriz com vetor simples
– Matriz m[i][j] com n colunas mapeada em um vetor v[k]
• k = i*n + j
j=1
i=2
a
p
c
d
e
f
g
r
z
x
o
b
a
p
c
d e
f
g
r
z
x
o
b
k = i*n + j = 2*4 + 1 = 9
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Matrizes Dinâmicas com
Vetor Simples
• Trecho de código para matriz com m linhas e n colunas
float a;
float *mat;
...
mat = (float*) malloc(m*n*sizeof(float));
a = mat[i*n + j];
...
Veja que a notação não é
intuitiva, como era no caso
de uma matriz estática
Computadores Digitais II– DETEL-FEN/UERJ
Acesso ao elemento m[i][j]
Prof. Rodrigo de Souza Couto
Exercício
• Crie uma função que retorne um ponteiro para a
matriz transposta de uma dada matriz
– Matriz transposta t
• matrizT[j][i] = mat[i][j]
– Matriz transposta deve ser alocada dinamicamente
dentro da função
– Matriz recebida foi alocada na função principal como um
vetor
– Protótipo da função
float* transposta(int nrLinhas, int nrColunas, float* mat);
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Exercício: Resposta
float* transposta(int nrLinhas, int nrColunas, float* mat){
int i, j;
float *matrizT;
/*Aloca matriz transposta*/
matrizT = (float*)malloc(nrColunas*nrLinhas*sizeof(float));
/*Preenche a matriz*/
for (i=0; i<nrLinhas; i++)
for (j=0; j< nrColunas; j++)
matrizT[j*nrLinhas + i] = mat[i*nrColunas + j];
return matrizT;
}
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Matrizes Dinâmicas com
Vetor de Ponteiros
• Cada elemento do vetor armazena o endereço do
primeiro elemento de cada linha da matriz
j=1
j=1
i=2
a
p
c
d
e
f
g
r
z
x
o
b
Computadores Digitais II– DETEL-FEN/UERJ
i=2
a
p
c
d
e
f
g
r
z
x
o
b
Prof. Rodrigo de Souza Couto
Matrizes Dinâmicas com
Vetor de Ponteiros
• Trecho de código para matriz com m linhas e n colunas
int i;
float a;
float **mat; /*Indica um vetor para ponteiros*/
...
mat = (float**) malloc(m*sizeof(float*));
for (i=0; i<m; i++)
mat[i] = (float*) malloc(n*sizeof(float));
a = mat[2][3];
...
Acesso ao elemento mat[2][3]
Grande vantagem do vetor de
ponteiros: Matrizes podem ser
tratadas como no caso
estático!
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Matrizes Dinâmicas com
Vetor de Ponteiros
• Liberação de memória
– Cada linha tem que ser liberada antes de se liberar o
vetor de ponteiros
...
for (i=0; i<m; i++)
free(mat[i]);
free(mat);
...
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Exercício
• Como no exercício anterior, crie uma função que
retorne um ponteiro para a matriz transposta de uma
dada matriz
– Matriz transposta t
• matrizT[j][i] = mat[i][j]
– Matriz transposta deve ser alocada dinamicamente
dentro da função
– Matriz recebida foi alocada na função principal como um
vetor de ponteiros
– Protótipo da função
float** transposta(int nrLinhas, int nrColunas, float** mat);
Computadores Digitais II– DETEL-FEN/UERJ
Prof. Rodrigo de Souza Couto
Exercício: Resposta
float** transposta(int nrLinhas, int nrColunas, float** mat){
int i, j;
float **matrizT;
/*Aloca matriz transposta*/
matrizT = (float*)malloc(nrColunas*sizeof(float*));
for (i=0; i<nrColunas; i++)
matrizT[i] = (float*)malloc(nrLinhas*sizeof(float));
/*Preenche a matriz*/
for (i=0; i<nrLinhas; i++)
for (j=0; j< nrColunas; j++)
matrizT[j][i] = mat[i][j];
return matrizT;
}
Download

Slides