You are on page 1of 50

Ponteiros

Prof. Roberto Hugo Wanderley Pinheiro


roberto.hugo@ufca.edu.br
Roteiro
Introdução
Motivação
Ponteiros
Declaração
Acesso
Aritmética
Exemplo
Detalhes
Alocação Dinâmica
Exemplo
Indireção Múltipla
Exemplo

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 2


Introdução
Um ponteiro é uma variável que contém um
endereço de memória
Endereço Variável
na memória na memória

1000 1003
1001
1002
1003
1004
1005
1006

Uma variável aponta para outra

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 3


Motivação
Ponteiros servem para
Permitir alteração dos valores de variáveis em
funções
Permitir alocação dinâmica de dados
• Vetores e matrizes de tamanho variáveis
• Estruturas de dados (listas, filas, pilhas)
Melhorar desempenho
Viver perigosamente com possibilidades de
explodir o computador
• Estudamos para isso

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 4


Declaração
Para declarar um ponteiro usamos *
int x, *y;

x é um variável inteira
y é um ponteiro para um inteiro

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 5


Acesso
O operador & serve para acessar o endereço de
uma variável
int x, *y;
y = &x;
printf("%p e %p", &x, y);
Nesse printf teremos dois valores iguais, pois o
ponteiro y recebeu o endereço da variável x
%p imprime um endereço de memória em
hexadecimal

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 6


Acesso
O operador * além da declaração serve para
acessar o valor de um determinado endereço
int x = 0, *y;
y = &x;
x = 10;
printf("%d", *y);

O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 7


Acesso
1000 0 x
int x = 0, *y; ... ... ...
1050 ? y

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 8


Acesso
1000 0 x
int x = 0, *y; ... ... ...
1050 ? y

1000 0 x
y = &x; ... ... ...
1050 1000 y

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 9


Acesso
1000 0 x
int x = 0, *y; ... ... ...
1050 ? y

1000 0 x
y = &x; ... ... ...
1050 1000 y

1000 10 x
x = 10; ... ... ...
1050 1000 y

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 10


Acesso
1000 0 x
int x = 0, *y; ... ... ...
1050 ? y

1000 0 x
y = &x; ... ... ...
1050 1000 y

1000 10 x
x = 10; ... ... ...
1050 1000 y

1000 10 x
printf("%d", *y); ... ... ... *y
1050 1000 y
Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 11
Acesso
E nesse exemplo...
int x = 10;
int *pi, *pj;
pi = &x;
pj = pi;
(*pi)++;
(*pj)++;
printf("%d", x);
O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 12


Acesso
E nesse exemplo...
int x = 10;
1000 10 x
int *pi, *pj;
pi = &x; . .
pj = pi; . .
. .
(*pi)++;
(*pj)++; 1050

printf("%d", x); 1051

O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 13


Acesso
E nesse exemplo...
int x = 10;
1000 10 x
int *pi, *pj;
pi = &x; . .
pj = pi; . .
. .
(*pi)++;
(*pj)++; 1050 pi

printf("%d", x); 1051 pj

O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 14


Acesso
E nesse exemplo...
int x = 10;
1000 10 x
int *pi, *pj;
pi = &x; . .
pj = pi; . .
. .
(*pi)++;
(*pj)++; 1050 1000 pi

printf("%d", x); 1051 pj

O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 15


Acesso
E nesse exemplo...
int x = 10;
1000 10 x
int *pi, *pj;
pi = &x; . .
pj = pi; . .
. .
(*pi)++;
(*pj)++; 1050 1000 pi

printf("%d", x); 1051 1000 pj

O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 16


Acesso
E nesse exemplo...
int x = 10;
1000 11 x
int *pi, *pj;
pi = &x; . .
pj = pi; . . *pi
. .
(*pi)++;
(*pj)++; 1050 1000 pi

printf("%d", x); 1051 1000 pj

O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 17


Acesso
E nesse exemplo...
int x = 10;
1000 12 x
int *pi, *pj;
pi = &x; . .
pj = pi; . .
*pj
. .
(*pi)++;
(*pj)++; 1050 1000 pi

printf("%d", x); 1051 1000 pj

O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 18


Acesso
E nesse exemplo...
int x = 10;
1000 12 x
int *pi, *pj;
pi = &x; . .
pj = pi; . .
. .
(*pi)++;
(*pj)++; 1050 1000 pi

printf("%d", x); 1051 1000 pj

O que vai ser impresso?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 19


Aritmética
É possível realizar operações sobre os
ponteiros, vale ressaltar que pode-se
Somar ou subtrair um inteiro de um ponteiro
Incrementar ou decrementar ponteiro
Subtrair ponteiros (produz um inteiro não um
ponteiro)
Comparar ponteiros

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 20


Aritmética
É possível acessar um ponteiro somando
quantos espaços de memória você quer
caminhar
int x[5] = {2,4,6,8,10};
int *y;
y = x;
printf("%d\n", *(y+3));

O que vai ser impresso?


Importante: vetores são ponteiros, por isso não precisamos do &
Inclusive, você pode navegar o ponteiro como vetor e o vetor como ponteiro
Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 21
Aritmética
1000 2 x
int x[5] = {2,4,6,8,10}; 1001 4
int *y; 1002 6 .
y = x; 1003 8 .
1004 10 .
...
1050 1000 y

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 22


Aritmética
1000 2 x
int x[5] = {2,4,6,8,10}; 1001 4
int *y; 1002 6 .
y = x; 1003 8 .
1004 10 .
...
1050 1000 y

1000 2 x
1001 4
1002 6 .
printf("%d\n", *(y+3)); 1003 8 .
// igual: y[3] 1004 10 .
*(y+3)
...
1050 1000 y
Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 23
Aritmética
1000 2 x
int x[5] = {2,4,6,8,10}; 1001 4
int *y; 1002 6 .
y = x; 1003 8 .
1004 10 .
...
1050 1000 y

1000 2 x
1001 4
1002 6 .
printf("%d\n", *(y+3)); 1003 8 .
// igual: y[3] 1004 10 .
*(y+3)
...
1050 1000 y
Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 24
Exemplo
0x00000000 ?
Cada célula de memória 0x00000001 ?
possui espaço para um byte 0x00000002 ?
e o endereçamento varia de 0x00000003 ?
acordo com a arquitetura 0x00000004 ?
0x00000005 ?

A memória ao lado é um 0x00000006 ?

trecho de uma memória de 0x00000007 ?


?
uma arquitetura de 32 bits, 0x00000008

?
por isso os endereços são 0x00000009

0x0000000A ?
representados por 8 0x0000000B ?
números em hexadecimal 0x0000000C ?
Em 1 hexadecimal cabem 4 0x0000000D ?
bits 0x0000000E ?
25

8 hexas x 4 bits = 32 bits 0x0000000F ?


0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 25


Exemplo
0x00000000 ?
O espaço que uma 0x00000001 ?
0x00000002 ?
variável ocupa na 0x00000003 ?
memória depende do 0x00000004 ?
0x00000005 ?
seu tipo 0x00000006 ?
0x00000007 ?
0x00000008 ?

Relembrando... 0x00000009 ?
0x0000000A ?
Tipo Espaço em Memória
0x0000000B ?
int 2 bytes
0x0000000C ?
long int 4 bytes 0x0000000D ?
char 1 byte 26
0x0000000E ?
float 4 bytes 0x0000000F ?
double 8 bytes 0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 26


Exemplo
0x00000000 ?
O espaço que uma 0x00000001 ?
0x00000002 ?
variável ocupa na 0x00000003 ?
memória depende do 0x00000004 ?
0x00000005 ?
seu tipo 0x00000006 ?
0x00000007 ?
0x00000008 ?

Relembrando... 0x00000009 ?
0x0000000A ?
Tipo Espaço em Memória
0x0000000B ?
int 2 bytes
0x0000000C ?
long int 4 bytes 0x0000000D ?
char 1 byte 27
0x0000000E ?
float 4 bytes 0x0000000F ?
double 8 bytes 0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 27


Exemplo
0x00000000 ?
a
Então, supondo... 0x00000001 ?
0x00000002 ? b
int a; 0x00000003 ?
0x00000004 ?
char b; 0x00000005 ?
c

0x00000006 ?
float c; 0x00000007 ?
0x00000008 ?
0x00000009 ?

Temos a memória ao 0x0000000A ?


0x0000000B ?
lado alocada 0x0000000C ?
0x0000000D ?
28
0x0000000E ?
0x0000000F ?
0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 28


Exemplo
0x00000000 ?
Um ponteiro, entretanto, é um a
0x00000001 ?
apontador de memória
0x00000002 ? b
Logo, qualquer declaração de
ponteiro ocupará um espaço de 0x00000003 ?
acordo com os bits da arquitetura, 0x00000004 ?
c
neste caso 32 bits 0x00000005 ?
1 bit = 8 bytes 0x00000006 ?
32 / 8 = 4 bytes (células) 0x00000007 ?
0x00000008 ?
d
Sendo assim, nessa situação 0x00000009 ?
int a; 0x0000000A ?
char b; 0x0000000B ?
float c; 0x0000000C ?
char *d; 0x0000000D ?
29
Temos a memória ao lado alocada 0x0000000E ?
0x0000000F ?
0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 29


Exemplo
0x00000000 00000000
Agora, suponha o 0x00000001 00011001
a

seguinte código: 0x00000002 01010000 b


0x00000003 00000000
int a; 0x00000004 00000000
c
char b; 0x00000005 00000000
0x00000006 00000010
char *c; 0x00000007 ?
?
a = 25; 0x00000008

0x00000009 ?
b = 'P'; P é 01010000 em ASCII 0x0000000A ?
0x0000000B ?
c = &b; 0x0000000C ?
Temos a memória ao lado 0x0000000D ?
30
alocada 0x0000000E

0x0000000F
?
?
0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 30


Exemplo
0x00000000 00000000
Se realizarmos as 0x00000001 00011001
a

seguintes operações 0x00000002 01000001 b


0x00000003 00000000 *c
*c = 'A'; A é 01000001 em ASCII 0x00000004 00000000
c
char *t = "TESTE"; 0x00000005 00000000
c = t; 0x00000006 00000010
0x00000007 00000000
while (*c != '\0') {
0x00000008 00000000
printf("%c", *c); t
0x00000009 00000000
c++; 0x0000000A 00001011
} 0x0000000B T *t
printf(" %s %c", t+3, b); 0x0000000C E
0x0000000D S
O que vai acontecer? 0x0000000E T
0x0000000F E
0x00000010 \0

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 31


Exemplo
0x00000000 00000000
Se realizarmos as 0x00000001 00011001
a

seguintes operações 0x00000002 01000001 b


0x00000003 00000000
*c = 'A'; A é 01000001 em ASCII 0x00000004 00000000
c
char *t = "TESTE"; 0x00000005 00000000
c = t; 0x00000006 00001011
0x00000007 00000000
while (*c != '\0') {
0x00000008 00000000
printf("%c", *c); t
0x00000009 00000000
c++; 0x0000000A 00001011
} 0x0000000B T *t
*c
printf(" %s %c", t+3, b); 0x0000000C E
0x0000000D S
O que vai acontecer? 0x0000000E T
0x0000000F E
Imprimiu na tela: T
0x00000010 \0

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 32


Exemplo
0x00000000 00000000
Se realizarmos as 0x00000001 00011001
a

seguintes operações 0x00000002 01000001 b


0x00000003 00000000
*c = 'A'; A é 01000001 em ASCII 0x00000004 00000000
c
char *t = "TESTE"; 0x00000005 00000000
c = t; 0x00000006 00001100
0x00000007 00000000
while (*c != '\0') {
0x00000008 00000000
printf("%c", *c); t
0x00000009 00000000
c++; 0x0000000A 00001011
} 0x0000000B T *t
printf(" %s %c", t+3, b); 0x0000000C E *c
0x0000000D S
O que vai acontecer? 0x0000000E T
0x0000000F E
Imprimiu na tela: TE
0x00000010 \0

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 33


Exemplo
0x00000000 00000000
Se realizarmos as 0x00000001 00011001
a

seguintes operações 0x00000002 01000001 b


0x00000003 00000000
*c = 'A'; A é 01000001 em ASCII 0x00000004 00000000
c
char *t = "TESTE"; 0x00000005 00000000
c = t; 0x00000006 00001101
0x00000007 00000000
while (*c != '\0') {
0x00000008 00000000
printf("%c", *c); t
0x00000009 00000000
c++; 0x0000000A 00001011
} 0x0000000B T *t
printf(" %s %c", t+3, b); 0x0000000C E
0x0000000D S *c
O que vai acontecer? 0x0000000E T
0x0000000F E
Imprimiu na tela: TES
0x00000010 \0

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 34


Exemplo
0x00000000 00000000
Se realizarmos as 0x00000001 00011001
a

seguintes operações 0x00000002 01000001 b


0x00000003 00000000
*c = 'A'; A é 01000001 em ASCII 0x00000004 00000000
c
char *t = "TESTE"; 0x00000005 00000000
c = t; 0x00000006 00010000
0x00000007 00000000
while (*c != '\0') {
0x00000008 00000000
printf("%c", *c); t
0x00000009 00000000
c++; 0x0000000A 00001011
} 0x0000000B T *t
printf(" %s %c", t+3, b); 0x0000000C E
0x0000000D S
O que vai acontecer? 0x0000000E T
0x0000000F E
Imprimiu na tela: TESTE
0x00000010 \0 *c
Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 35
Exemplo
0x00000000 00000000
Se realizarmos as 0x00000001 00011001
a

seguintes operações 0x00000002 01000001 b


0x00000003 00000000
*c = 'A'; A é 01000001 em ASCII 0x00000004 00000000
c
char *t = "TESTE"; 0x00000005 00000000
c = t; 0x00000006 00010000
0x00000007 00000000
while (*c != '\0') {
0x00000008 00000000
printf("%c", *c); t
0x00000009 00000000
c++; 0x0000000A 00001011
} 0x0000000B T *t
printf(" %s %c", t+3, b); 0x0000000C E
0x0000000D S
O que vai acontecer? 0x0000000E T
0x0000000F E
Imprimiu na tela: TESTE TE A
0x00000010 \0 *c
Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 36
Detalhes
Operações válidas
Somar ou subtrair um inteiro a um ponteiro
Incrementar ou decrementar ponteiro
Subtrair ponteiros
• Produz um inteiro, não um ponteiro
Comparar ponteiros

Operações inválidas
Somar ponteiros
Usar multiplicação ou divisão com ponteiro
Operar ponteiros com double ou float

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 37


Detalhes
C não controla os limites dos vetores ou de ponteiros
caminhantes
Então, cuidado para não acessar memória que não foi
alocada

Um ponteiro deve sempre apontar para um local válido


antes de ser utilizado
Caso contrário dá erro mesmo

É possível colocar o valor NULL em um ponteiro, isso


pode ser útil em alguns casos
int *p;
p = NULL;

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 38


Detalhes
Existe ponteiro do tipo genérico
Basta declará-lo como tipo void

O problema é que ele precisa ser controlado para com conversões de


dados

Exemplo
void *pv;
int n = 10;
float f = 3.5;
pv = &n;
printf("Inteiro: %d\n", *(int *)pv);
pv = &f;
printf("Real: %f\n", *(float *)pv);

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 39


Exercício em Sala
Escreva um programa que imprima um vetor
de inteiros com 10 posições na ordem inversa
endereçando os elementos com um ponteiro

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 40


Exercício em Sala
#include <stdio.h>

int main () {
int x[10], i, *p;
for (i = 0 ; i < 10 ; i++) {
scanf("%d", &x[i]);
}
p = x + 9; // Por que não 10?
for (i = 0 ; i < 10 ; i++) {
printf("%d ", *p);
p--;
}
return 0;
}

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 41


Alocação Dinâmica
Geralmente trabalhamos com alocação de
memória estática
Tamanho fixo e imutável

Alocação de memória dinâmica é justamente o


contrário
Tamanho variável e mutável

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 42


Alocação Dinâmica
Para realização da Alocação Dinâmica, vamos
precisar de algumas funções
Função Utilidade
malloc() Alocação inicial da memória
sizeof() Tamanho de uma variável (em bytes) ou tipo de variável
realloc() Realoca uma variável previamente alocada
free() Libera espaço de memória de uma variável alocada

Não esqueça de #include <stdlib.h>

Vamos para um exemplo clássico de aplicação


Vetor crescente

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 43


Exemplo
0x00000000 ?
int main () { i
0x00000001 ?
int i, val, *v, tam;
0x00000002
tam = 0; val
v = (int *)malloc(sizeof(int)); 0x00000003 22
scanf("%d", &val); 0x00000004 00000000
while (val != -1) { 0x00000005 00000000
v
tam++; 0x00000006 00000000
v = (int *)realloc(v, tam * 0x00000007 00001010
v[tam-1] = val; sizeof(int)); 0x00000008
scanf("%d", &val); tam
0x00000009 0
}
0x0000000A ? *v
for (i = 0 ; i < tam ; i++) {
0x0000000B ?
printf("%d ", v[i]);
0x0000000C ?
}
free(v);
0x0000000D ?

return 0; Variáveis inteiras escritas 0x0000000E ?


} em decimal para 0x0000000F ?
facilitar leitura 0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 44


Exemplo
0x00000000 ?
int main () { i
0x00000001 ?
int i, val, *v, tam;
0x00000002
tam = 0; val
v = (int *)malloc(sizeof(int)); 0x00000003 58
scanf("%d", &val); 0x00000004 00000000
while (val != -1) { 0x00000005 00000000
v
tam++; 0x00000006 00000000
v = (int *)realloc(v, tam * 0x00000007 00001010
v[tam-1] = val; sizeof(int)); 0x00000008
scanf("%d", &val); tam
0x00000009 1
}
0x0000000A *v
for (i = 0 ; i < tam ; i++) {
0x0000000B 22
printf("%d ", v[i]);
0x0000000C ?
}
free(v);
0x0000000D ?

return 0; 0x0000000E ?
} 0x0000000F ?
0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 45


Exemplo
0x00000000 ?
int main () { i
0x00000001 ?
int i, val, *v, tam;
0x00000002
tam = 0; val
v = (int *)malloc(sizeof(int)); 0x00000003 35
scanf("%d", &val); 0x00000004 00000000
while (val != -1) { 0x00000005 00000000
v
tam++; 0x00000006 00000000
v = (int *)realloc(v, tam * 0x00000007 00001010
v[tam-1] = val; sizeof(int)); 0x00000008
scanf("%d", &val); tam
0x00000009 2
}
0x0000000A *v
for (i = 0 ; i < tam ; i++) {
0x0000000B 22
printf("%d ", v[i]);
0x0000000C
}
free(v);
0x0000000D 58

return 0; 0x0000000E ?
} 0x0000000F ?
0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 46


Exemplo
0x00000000 ?
int main () { i
0x00000001 ?
int i, val, *v, tam;
0x00000002
tam = 0; val
v = (int *)malloc(sizeof(int)); 0x00000003 -1
scanf("%d", &val); 0x00000004 00000000
while (val != -1) { 0x00000005 00000000
v
tam++; 0x00000006 00000000
v = (int *)realloc(v, tam * 0x00000007 00001010
v[tam-1] = val; sizeof(int)); 0x00000008
scanf("%d", &val); tam
0x00000009 3
}
0x0000000A *v
for (i = 0 ; i < tam ; i++) {
0x0000000B 22
printf("%d ", v[i]);
0x0000000C
}
free(v);
0x0000000D 58
0x0000000E
return 0;
} 0x0000000F 35
0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 47


Exemplo
0x00000000
int main () { i
0x00000001 0
int i, val, *v, tam;
0x00000002
tam = 0; val
v = (int *)malloc(sizeof(int)); 0x00000003 -1
scanf("%d", &val); 0x00000004 00000000
while (val != -1) { 0x00000005 00000000
v
tam++; 0x00000006 00000000
v = (int *)realloc(v, tam * 0x00000007 00001010
v[tam-1] = val; sizeof(int)); 0x00000008
scanf("%d", &val); tam
0x00000009 3
}
0x0000000A *v
for (i = 0 ; i < tam ; i++) {
0x0000000B 22 v[0]
printf("%d ", v[i]);
0x0000000C
}
free(v);
0x0000000D 58 v[1]
0x0000000E
return 0;
} 0x0000000F 35 v[2]
0x00000010 ?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 48


Indireção Múltipla
Vulgo ponteiro de ponteiro

Serve para gerar matrizes dinâmicas


float **notas;

Nada impede também de ponteiro de ponteiro de


ponteiro... Mas não vamos nos deixar levar
int ***vídeo;

Então, como declarar uma matriz dinamicamente?

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 49


Indireção Múltipla
#include <stdio.h>
#include <stdlib.h>

int main(){
float **v;
int i, j, n, m;
scanf("%d", &n); // Linhas
scanf("%d", &m); // Colunas
v = (float **)malloc(n * sizeof(float *));
for (i = 0 ; i < n ; i++)
v[i] = (float *)malloc(m * sizeof(float));

for (i = 0 ; i < n ; i++)


for (j = 0 ; j < m ; j++)
scanf("%f", &v[i][j]);

return 0;
}

Prof. Roberto Pinheiro Introdução à Programação (CC0001 e MC0004) 50

You might also like