Você está na página 1de 33

Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Algoritmos e Estrutura de Dados II

Aula 03 - Ponteiros e Alocação Dinâmica de Memória

P ONTIFÍCIA U NIVERSIDADE C ATÓLICA DE M INAS G ERAIS


Instituto de Ciências Exatas e Informática

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Agenda

1 Ponteiros

2 Alocação Dinâmica de Memória

3 Alocação de Vetores

4 Alocação de Matrizes

5 Alocação de Estruturas

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

O que são ponteiros?

Ponteiro
Um ponteiro é um endereço de memória. Seu valor indica
onde uma variável está armazenada, não o que está
armazenado. Um ponteiro proporciona um modo de acesso a
uma variável sem referência-la diretamente.

Exemplo
O que é o ponteiro de um relógio? É o que aponta para as
horas, minutos ou segundos. Um ponteiro aponta para algo.
Em programação, temos as variáveis armazenadas na
memória, e um ponteiro aponta para um endereço de memória.

Não se desespere caso não consiga entender num primeiro


momento, o conceito fica mais claro com a prática!
Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II
Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Porque os ponteiros são usados?

Para dominar a linguagem C, é essencial dominar


ponteiros. Os ponteiros são usados em situações em que
o uso de uma variável é difícil ou indesejado.
Algumas razões para o uso de ponteiros:
Manipular elementos de matrizes
receber argumentos em funções que necessitem modificar
o argumento original
passar strings de uma função para outra; usá-los no lugar
de matrizes
criar estruturas de dados complexas, como listas
encadeadas e árvores binárias, onde um item deve conter
referências a outro;
alocar e desalocar memória do sistema

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Endereços de Memória
A memória de seu computador é dividida em bytes , e estes bytes são
numerados de 0 até o limite de sua maquina. Estes números são
chamados endereços de bytes. Um endereço é a referência que o
computador usa para localizar variáveis.
Toda variável ocupa certa localização na memória, e seu endereço é o
do primeiro byte ocupado por ela.

Nossos programas, quando carregados para a memória, ocupam uma


certa parte dela. Dessa forma, toda variável e toda função de nosso
programa começam em um endereço particular, e este endereço é
chamado endereço da variável ou função.

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

O operador de endereços &


Para conhecermos o endereço ocupado por uma variável
usamos o operador de endereços (&).
Exemplo

1 #include <stdio.h>
2 int main(){
3 int i, j, k;
4 printf("%p\n%p\n%p\n",&i,&j,&k);
5 return 0;
6 }

Resultado
0028FF1C
0028FF18
0028FF14
Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II
Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Declarando Ponteiros
Um ponteiro, como qualquer variável, deve ter um tipo, que
é o tipo da variável para a qual ele aponta.
Para declarar um ponteiro, especificamos o tipo da
variável para a qual ele aponta e seu nome precedido por
asterisco:

1 int ponteiro; // declara uma variavel comum do tipo inteiro


2 int *ponteiro; // declara um ponteiro para um inteiro

Tome cuidado ao declarar vários ponteiros em uma linha,


pois o asterisco deve vir antes de cada nome de variável.
Note os três exemplos:

1 int p, q, r; // estamos a declarar tres variaveis comuns


2 int *p, q, r; // cuidado! apenas p sera um ponteiro!
3 int *p, *q, *r; // agora sim temos tres ponteiros

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Declarando Ponteiros
Para atribuir um valor ao ponteiro, usamos apenas seu
nome de variável. Esse valor deve ser um endereço de
memória, portanto obtido com o operador &:

1 int a;
2 int *p;
3 p = &a;

Claro que também podemos inicializar um ponteiro:

1 int *p = &a;

Nos dois casos, o ponteiro p Algoritmos


irá apontar
Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br
para a variável a.
e Estrutura de Dados II
Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Declarando Ponteiros

Como o ponteiro contém um endereço, podemos também


atribuir um valor à variável guardada nesse endereço, ou
seja, à variável apontada pelo ponteiro. Para isso, usamos
o operador * (asterisco), que basicamente significa "o valor
apontado por".

1 #include <stdio.h>
2 int main(){
3 int i = 10 ;
4 int *p = &i ;
5 *p = 5 ;
6 printf ("%d\t%d\t%p\n", i, *p, p);
7 return 0;
8 }

5 5 0028FF18
Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II
Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Ponteiro e NULL
Uma falha de segmentação ou em inglês (segmentation
fault) ocorre quando um programa tenta acessar um
endereço na memória que está reservado ou que não
existe.
Aqui o ponteiro contem NULL, definido com o endereço
(0x00000000) que causa uma falha de segmentação.
É sempre bom inicializarmos os ponteiros, pois senão eles
podem vir com lixo e você se esquecer, posteriormente, de
inicializar.
Uma boa prática é apontar os ponteiros para a primeira
posição de memória, ou seja, NULL.
Exemplo

1 int *p = NULL;

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Operação com Ponteiros

Suponhamos dois ponteiros inicializados p1 e p2.


Podemos fazer dois tipos de atribuição entre eles:
1 Esse primeiro exemplo fará com que p1 aponte para o
mesmo lugar que p2. Ou seja, usar p1 será equivalente a
usar p2 após essa atribuição.

1 p1 = p2;

2 Nesse segundo caso, estamos a igualar os valores


apontados pelos dois ponteiros: alteraremos o valor
apontado por p1 para o valor apontado por p2.

1 *p1 = *p2;

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Ponteiros e vetores
Em C, os elementos de um vetor são sempre guardados
sequencialmente, a uma distância fixa um do outro.
Com isso, é possível facilmente passar de um elemento a outro,
percorrendo sempre uma mesma distância para frente ou para trás na
memória.
Dessa maneira, podemos usar ponteiros e a aritmética de ponteiros
para percorrer vetores. Na verdade, vetores são ponteiros - um uso
particular dos ponteiros.

1 #include <stdio.h>
2 int main (){
3 int i;
4 int vetorTeste[3] = {4, 7, 1};
5 int *ptr = vetorTeste;
6 printf("%p\n", vetorTeste);
7 printf("%p\n", ptr);
8 for (i = 0; i < 3; i++) {
9 printf("O endereco do indice %d do vetor eh %p\n", i, &ptr[i]);
10 printf("O valor do indice %d do vetor eh %d\n", i, ptr[i]);
11 }
12 return 0;
13 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Ponteiro de estrutura
Assim como em qualquer outro tipo de dados também
podemos manipular as informações de uma estrutura
através de ponteiros.
A partir do ponteiro podemos ter acesso a um campo da
estrutura usando um seletor "− >"(uma flecha).

1 #include <stdio.h>
2 #include <string.h>
3 struct PRODUTO{
4 int codigo;
5 char descricao[100];
6 };
7 int main(){
8 struct PRODUTO produto;
9 struct PRODUTO *ptr_produto = &produto;
10 ptr_produto->codigo = 1;
11 strcpy((*ptr_produto).descricao,"Chocolate");
12 printf("Codigo do Produto: %d\n",produto.codigo);
13 printf("Descricao do Produto: %s\n",ptr_produto->descricao);
14 return 0;
15 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Revisão: Passando Argumentos por referência


Qual será o resultado do programa abaixo?

1 #include <stdio.h>
2 void trocar(int num1, int num2){
3 int temp;
4 temp = num1;
5 num1 = num2;
6 num2 = temp;
7 }
8 int main(){
9 int a, b;
10 a = 5;
11 b = 10;
12 printf ("\n\nEles valem %d, %d\n", a, b);
13 trocar (a, b);
14 printf ("\n\nEles agora valem %d, %d\n", a, b);
15 return 0;
16 }
Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II
Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Revisão: Passando Argumentos por referência


A troca não é realizada devido ao escopo das variáveis
serem locais na função trocar!
Neste caso podemos usar a passagem do argumento
como referência para que a troca seja feita na função e
continue efetiva dentro da função principal.

1 #include <stdio.h>
2 void trocar(int &num1, int &num2){
3 int temp;
4 temp = num1;
5 num1 = num2;
6 num2 = temp;
7 }
8 int main(){
9 int a, b;
10 a = 5;
11 b = 10;
12 printf ("\n\nEles valem %d, %d\n", a, b);
13 trocar (a, b);
14 printf ("\n\nEles agora valem %d, %d\n", a, b);
15 return 0;
16 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Revisão: Passando Argumentos por referência


Também podemos usar ponteiros para fazer a mesma
coisa!

1 #include <stdio.h>
2 void trocar(int *num1, int *num2){
3 int temp;
4 temp = *num1;
5 *num1 = *num2;
6 *num2 = temp;
7 }
8 int main(){
9 int a, b;
10 a = 5;
11 b = 10;
12 printf ("\n\nEles valem %d, %d\n", a, b);
13 trocar (&a, &b);
14 printf ("\n\nEles agora valem %d, %d\n", a, b);
15 return 0;
16 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Revisão: Passando Argumentos por referência

E este código? Funciona?

1 #include <stdio.h>
2 void trocar(int num[]){
3 int temp;
4 temp = num[0];
5 num[0] = num[1];
6 num[1] = temp;
7 }
8 int main(){
9 int numeros[2];
10 numeros[0] = 5;
11 numeros[1] = 10;
12 printf ("Eles valem %d,%d\n",numeros[0],numeros[1]);
13 trocar (numeros);
14 printf ("Eles agora valem %d,%d\n",numeros[0],numeros[1]);
15 return 0;
16 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Revisão: Passando Argumentos por referência

Sim! É a mesma coisa que passar o vetor usando ponteiro!

1 #include <stdio.h>
2 void trocar(int *num){
3 int temp;
4 temp = num[0];
5 num[0] = num[1];
6 num[1] = temp;
7 }
8 int main(){
9 int numeros[2];
10 numeros[0] = 5;
11 numeros[1] = 10;
12 printf ("Eles valem %d,%d\n",numeros[0],numeros[1]);
13 trocar (numeros);
14 printf ("Eles agora valem %d,%d\n",numeros[0],numeros[1]);
15 return 0;
16 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Alocação Dinâmica

Todos os dados de um programa são armazenados na


memória do computador; é muito comum necessitar
reservar um certo espaço na memória para poder guardar
dados mais tarde.
Por exemplo, poderíamos reservar um espaço de 1000
bytes para guardar uma string que o usuário viesse a
digitar, declarando um vetor de 1000 caracteres.
E se quiséssemos reservar um espaço que só é
conhecido no tempo de execução do programa?
E se o espaço fosse muito grande, de modo que declarar
vetores de tal tamanho seria inconveniente (pois, entre
outras coisas, aumenta sem necessidade o tamanho do
executável)?

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Alocação Dinâmica

Para solucionar esse problema, existe a alocação


dinâmica de memória, que como o nome sugere, é uma
maneira de alocar memória à medida que o programa vai
sendo executado.
A alocação dinâmica é gerenciada pelas funções malloc e
free, que estão na biblioteca <stdlib.h>.
Essas duas funções são as mais básicas para o
gerenciamento de memória. malloc é responsável pela
alocação de um pedaço de memória, e free é
responsável por liberar esse pedaço de memória.

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

malloc e free
A função malloc (abreviatura de memory allocation) aloca um bloco de
bytes consecutivos na memória do computador e devolve o endereço
desse bloco. O número de bytes é especificado no argumento da
função.
A função free é responsável por liberar a memória alocada.

1 void *malloc (unsigned int num);


2 void free (void * ptr);

Para alocar um espaço na memória, precisamos fornecer à função


malloc o número de bytes desejados.
Ela aloca na memória e retorna um ponteiro void* para o primeiro byte
alocado.
O ponteiro void* pode ser atribuído a qualquer tipo de ponteiro.
Se não houver memória suficiente para alocar a memória requisitada a
função malloc() retorna um ponteiro nulo(NULL).

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

malloc e free

1 #include <stdio.h>
2 #include <stdlib.h>
3 int main(){
4 // alocacao estatica
5 int a;
6 // alocacao dinamica
7 int *p = (int*)malloc(sizeof(int));
8 if ( p == NULL ){
9 printf ("Nao foi possivel alocar memoria!\n");
10 exit(1);
11 }
12 a = 10;
13 *p = 5;
14 printf("Numeros: %d - %d\n\n",a,*p);
15 free(p);
16 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

calloc

A função calloc() também serve para alocar memória, mas possui um


protótipo um pouco diferente:

1 void *calloc(size_t nelem, size_t elsize);

A função calloc reserva um bloco com o tamanho (nelem x elsize)


octetos consecutivos, isto é, aloca memória suficiente para um vetor de
num objetos de tamanho size.
Diferente de malloc(), o bloco reservado é inicializado a 0.
Essa função retorna um ponteiro void* para o primeiro byte alocado.
O ponteiro void* pode ser atribuído a qualquer tipo de ponteiro.
Se não houver memória suficiente para alocar a memória requisitada a
função calloc() retorna um ponteiro nulo (NULL).

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

calloc

1 #include <stdio.h>
2 #include <stdlib.h>
3 int main (){
4 int n=10;
5 int *p = (int *)calloc(n, sizeof(int));
6 if (p == NULL) {
7 printf ("** Erro: Memoria Insuficiente **");
8 exit(0);
9 }
10 for (int i=0; i<n; i++)
11 p[i] = i*i;
12
13 for (int i=0; i<n; i++)
14 printf("\n%d",p[i]);
15
16 free(p);
17 return 0;
18 }
Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II
Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Alocação Dinâmica de Vetores

1 #include <stdio.h>
2 #include <stdlib.h>
3 float *Alocar_vetor_real (int n){
4 if (n < 1){
5 printf ("** Erro: Parametro invalido **\n");
6 return (NULL);
7 }
8 float * v = (float*)calloc (n, sizeof(float));
9 if (v == NULL){
10 printf ("** Erro: Memoria Insuficiente **");
11 return (NULL);
12 }
13 return (v);
14 }
15 void Liberar_vetor_real (float *v){
16 if (v != NULL)
17 free(v);
18 }
Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II
Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Alocação Dinâmica de Vetores

1 int main (void)


2 {
3 int TAM;
4 char aux[100];
5 do{
6 printf("Digite o tamanho de TAM (> 0): ");
7 gets(aux);
8 TAM = atoi(aux);
9 }while(TAM <=0);
10
11 float *vetor_real = Alocar_vetor_real(TAM);
12
13 for (int i=0; i<TAM; i++)
14 vetor_real[i] = i;
15
16 for (int i=0; i<TAM; i++)
17 printf("\n%.2f",vetor_real[i]);
18
19 Liberar_vetor_real (vetor_real);
20 return 0;
21 }
Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II
Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Alocação Dinâmica de Matrizes

1 #include <stdio.h>
2 #include <stdlib.h>
3 int **Alocar_matriz (int m, int n){
4 if (m < 1 || n < 1){
5 printf ("** Erro: Parametro invalido **\n"); return (NULL);
6 }
7 int **matriz = (int **)calloc (m, sizeof(int*));
8 if (matriz == NULL){
9 printf ("** Erro: Memoria Insuficiente **"); return (NULL);
10 }
11 for (int i = 0; i < m; i++ ){
12 matriz[i] = (int*)calloc (n, sizeof(int));
13 if (matriz[i] == NULL){
14 printf ("** Erro: Memoria Insuficiente **"); return (NULL);
15 }
16 }
17 return (matriz);
18 }
19 void Liberar_matriz (int m, int n, int **mat){
20 if (mat != NULL)
21 if (m < 1 || n < 1)
22 printf ("** Erro: Parametro invalido **\n");
23 else{
24 for (int i=0; i<m; i++)
25 free (mat[i]);
26 free (mat);
27 }
28 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Alocação Dinâmica de Matrizes

1 int main (void){


2 int TAM_M, TAM_N;
3 char aux[100];
4 do{
5 printf("Digite o tamanho de TAM_M (> 0): ");
6 gets(aux);
7 TAM_M = atoi(aux);
8 }while(TAM_M <=0);
9 do{
10 printf("Digite o tamanho de TAM_N (> 0): ");
11 gets(aux);
12 TAM_N = atoi(aux);
13 }while(TAM_N <=0);
14
15 int **MATRIZ = Alocar_matriz(TAM_M,TAM_N);
16
17 for (int i=0; i<TAM_M; i++)
18 for (int j=0; j<TAM_N; j++)
19 MATRIZ[i][j] = i + j;
20 for (int i=0; i<TAM_M; i++){
21 for (int j=0; j<TAM_N; j++)
22 printf("%d ",MATRIZ[i][j]);
23 printf("\n");
24 }
25 Liberar_matriz(TAM_M,TAM_N,MATRIZ);
26 return 0;
27 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Alocação Dinâmica de Estruturas

1 #include <stdio.h>
2 #include <stdlib.h>
3 typedef struct{
4 int dia, mes, ano;
5 } DATA;
6 int main(){
7 int TAM=0;
8 char aux[100];
9 do{
10 printf("\nDigite o valor de TAM: ");
11 gets(aux);
12 TAM = atoi(aux);
13 }
14 while(TAM < 0);
15 DATA *datas = (DATA*)malloc(sizeof(DATA) * TAM);
16 if (datas == NULL){
17 printf ("** Erro: Memoria Insuficiente **"); exit(0);
18 }
19 for(int i=0;i<TAM;i++){
20 datas[i].dia = rand()%28 + 1;
21 datas[i].mes = rand()%12 + 1;
22 datas[i].ano = 2000 + rand()%12;
23 }
24 for(int i=0;i<TAM;i++)
25 printf("Dia: %d/%d/%d\n",datas[i].dia,datas[i].mes,datas[i].ano);
26 free(datas);
27 return 0;
28 }

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Exercícios

1 Faça um programa que acha o maior e o menor inteiro


dentro de um vetor de 10 inteiros. O vetor pode ser
preenchido de forma aleatória ou informado pelo usuário.
Obs: usar apenas as variáveis a seguir:
int *vetor, i, *maior, *menor;

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Exercícios

2 Escreva um programa em linguagem C que solicita ao


usuário a quantidade de alunos de uma turma e aloca um
vetor de notas (números reais). Depois de ler as notas,
imprime a média aritmética.
Obs: não deve ocorrer desperdício de memória; e após
ser utilizada a memória deve ser devolvida.

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Exercícios

3 Desenvolva um programa que calcule a soma de duas


matrizes MxN de números reais (double). A
implementação deste programa deve considerar as
dimensões fornecida pelo usuário (Dica: represente a
matriz através de variáveis do tipo double **, usando
alocação dinâmica de memória)..

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II


Ponteiros Alocação Dinâmica de Memória Alocação de Vetores Alocação de Matrizes Alocação de Estruturas

Dúvidas?

Prof. Kleber Jacques F. de Souza | klebersouza@pucminas.br Algoritmos e Estrutura de Dados II

Você também pode gostar