Você está na página 1de 9

Lista de exerccios - Alocao dinmica

Andr Murbach Maidl


Escola Politcnica PUCPR Curitiba Brasil
andre.murbach@pucpr.br

1. Escreva um programa que define a constante ARRAYSIZE, por exemplo,


#define ARRAYSIZE 10. Implemente uma funo que aloca um vetor de
ARRAYSIZE posies, inicializa cada posio do vetor com o mesmo nmero
do seu ndice e retorna o endereo de memria que foi alocado. Tambm
implemente uma funo main que chama a funo que voc criou e em
seguida imprime o vetor que comea no endereo de memria por ela retornado. Uma vez que voc fez este programa, altere o valor de ARRAYSIZE
e observe o resultado.
2. Usando a funo de alocao de memria malloc, escreva uma funo
somavets, a qual recebe dois vetores de inteiros e um tamanho como argumentos e retorna um ponteiro para o novo vetor desse tamanho (criado
com malloc), contendo em cada posio a soma dos valores das posies correspondentes nos vetores originais. Essa funo deve obedecer o
seguinte prottipo:
int* somavets (int a[], int b[], int n);
Escreva tambm uma funo main para testar a sua funo somavets.
Ela deve declarar dois vetores de inteiros, inicializando-os com alguns valores, e um ponteiro para receber o resultado de somavets. Aps chamar
somavets, sua main deve mostrar na tela o contedo dos trs vetores.
Voc tambm deve tratar o resultado de malloc, para o caso de no haver memria disponvel. Neste caso, somavets dever retornar NULL para
indicar o erro, e a sua main dever tratar esse resultado adequadamente.
3. Modifique a funo somavets do exerccio anterior para tambm receber
como parmetro o vetor que receber as somas. Essa funo deve obedecer
o seguinte prottipo:
void somavets (int a[], int b[], int soma[], int n);
Escreva tambm uma funo main para testar a sua nova funo somavets.
Onde deve ser realizado o malloc do vetor soma?

4. Em C, strings (cadeias de caracteres) como alo alo e Fulano de Tal


so representadas por vetores do tipo char terminados pelo caractere nulo
(\0, cujo valor ASCII 0). Essa converso usada, por exemplo, pela
funo printf, para imprimir uma cadeia de caracteres com o especificador "%s". Assim, quando escrevemos:
char nome[] = "Fulano de Tal";
estamos de fato alocando um vetor de 17 posies. Usando malloc, escreva uma funo duplica, a qual recebe como argumento uma cadeia de
caracteres e retorna uma cpia idntica dessa cadeia. Teste a sua funo
com o cdigo abaixo, e explique a sada do programa.
#include <stdio.h>
#include <stdlib.h>
char* duplica (char *orig) {
/* descobre o tamanho de orig (no esquea da posio do \0) */
/* aloca espao com malloc */
/* copia do original para o novo */
/* retorna ponteiro para novo vetor */
}
int main (void) {
char s[] = "alo alo";
char *ps;
ps = duplica (s);
if (ps == NULL) {
/* mensagem de erro e retorno que indica o erro */
}
s[2] = O;
printf ("%s - %s\n", s, ps);
free(ps);
return 0;
}
5. Implemente uma funo que seleciona todos os valores de um vetor que
so maiores do que um valor x especificado e armazena estes valores em
uma rea alocada dinamicamente, ou seja, em um novo vetor. Essa funo
deve obedecer o seguinte prottipo:
int* lista_maiores (int* vet, int n, int x, int* qtd);
Os parmetros da funo so:
vet: um vetor de inteiros;
2

n: a quantidade de elementos no vetor vet;


x: um nmero inteiro;
qtd: um ponteiro para um inteiro.
Essa funo deve:
(a) verificar a quantidade de elementos do vetor vet que so maiores que
x;
(b) caso a quantidade seja maior do que zero, alocar dinamicamente uma
rea do exato tamanho necessrio para armazenar os valores;
(c) copiar os elementos do vetor que so maiores do que x para a rea
alocada dinamicamente.
O retorno da funo o endereo da rea alocada dinamicamente que contm os nmeros maiores do que x, ou NULL, caso essa relao de nmeros
no tenha sido criada. Alm disso, a quantidade de nmeros armazenados
na rea alocada dinamicamente deve ser retornada ao chamador da funo
via o ponteiro qtd. Para testar o seu programa use nele a seguinte funo
main. Porm, nesta main falta uma chamada funo free. Corrija isto
adicionando o free no lugar correto.
#include <stdio.h>
#include <stdlib.h>
int* lista_maiores (int* vet, int n, int x, int* qtd) {
/* implemente a funo */
}
void imprime_vetor (int* vet, int n) {
int i;
printf("[");
for (i = 0; i < n - 1; i++) {
printf("%d, ", vet[i]);
}
printf("%d]\n", vet[n - 1]);
}
int main() {
int i;
int numeros[10] = {35, 10, 18, 9, 12, 60, 33, 15, 2, 8};
int limite;
int* maiores;
int n_maiores;
printf("Vetor original = ");
imprime_vetor(numeros, 10);
3

while (1) {
printf("Digite o valor limite (tecle -1 para sair): ");
scanf("%d", &limite);
if (limite == -1) {
break;
}
maiores = lista_maiores(numeros, 10, limite, &n_maiores);
if (maiores == NULL) {
printf("Nada a declarar!\n");
}
else {
printf("Valores maiores do que %d = ", limite);
imprime_vetor(maiores, n_maiores);
}
}
return 0;
}
6. Escreva uma funo troca_letras que recebe como parmetro o endereo
de uma cadeia de caracteres e retorna um ponteiro para uma nova cadeia
(alocada dinamicamente), onde todas as letras minsculas da cadeia original foram trocadas por maisculas e vice-versa. Caracteres que no so
letras (como dgitos, ., espao, etc.) no devem ser trocados. Essa funo
deve obedecer o seguinte prottipo:
char* troca_letras (char* s);
Na implementao de troca_letras voc pode usar as seguintes funes
da biblioteca padro:
strlen (descrita em string.h), que recebe o endereo de uma cadeia
(um char *) e retorna o nmero de caracteres nessa cadeia (sem
contar o \0);
isalpha, islower, isupper, toupper e tolower (descritas em ctype.h),
as quais recebem como parmetro um caractere. A funo isalpha
verifica se o caractere recebido uma letra (retorna verdadeiro) ou
no (retorna falso). A funo islower verifica se o caractere recebido
uma letra minscula (retorna verdadeiro) ou no (retorna falso); a
funo isupper faz o contrrio (isto , verifica se o caractere uma
letra maiscula). A funo toupper retorna um caractere que a
maiscula da letra minscula recebida; a funo tolower faz o contrrio. Caso no consiga alocar memria, a sua funo troca_letras
deve retornar NULL.
4

Teste a sua funo troca_letras com o cdigo abaixo. Note que o formato passado para scanf permite a leitura de cadeias contendo espaos e
que o programa termina quando o usurio digita uma cadeia que comea
com um .. Teste troca_letras com alguns exemplos de cadeias, com
letras minsculas e maisculas e caracteres que no so letras. Verifique se
a sada do seu programa est correta, ou seja, se sua funo troca_letras
faz o que deveria fazer.
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<string.h>
<ctype.h>

char *troca_letras(char *s) {


/* implementao da funo */
}
int main(void) {
char string[81];
char *ns;
while (1) {
printf("\nEntre uma cadeia: ");
scanf(" %80[^\n]", string);
if (*string == .) break;
ns = troca_letras(string);
if (ns != NULL) {
printf("Nova cadeia: %s\n", ns);
free(ns);
}
else
printf("Falha na troca!\n");
}
return 0;
}
7. Escreva uma funo inverte que recebe como parmetro uma cadeia de
caracteres e retorna uma nova cadeia, a qual corresponde cadeia original, lida de trs para frente. Por exemplo, recebendo como parmetro a
cadeia Aluno, essa funo retornaria a cadeia onulA. Essa funo deve
obedecer o seguinte prottipo:
char* inverte (char* s);
Adapte a funo main do exerccio anterior para testar inverte.
8. Escreva uma funo ultimo_nome que recebe como parmetro uma cadeia
com o nome completo de uma pessoa e retorna um ponteiro (o endereo
5

inicial) do ltimo nome encontrado. Note que voc no deve alocar uma
nova cadeia para retornar o ltimo nome. Essa funo deve obedecer o
seguinte prottipo:
char* ultimo_nome (char *nome_completo);
Veja alguns exemplos:
para a cadeia Dennis MacAlistair Ritchie a sua funo deve retornar
Ritchie;
para a cadeia Brian Wilson Kernighan a sua funo deve retornar
Kernighan;
para a cadeia Fulano a sua funo deve retornar Fulano.
Assuma que h apenas um espao entre os nomes e que aps o ltimo
nome no h espaos. Adapte a funo main do exerccio anterior para
testar ultimo_nome. Note que agora no h liberao de memria.
9. Considere o programa de cadastro de alunos a seguir:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct aluno {
char nome[81];
int mat;
} Aluno;
/* Cria uma nova estrutura Aluno com dados lidos do teclado */
Aluno* lealuno() {
Aluno* a = (Aluno*) malloc(sizeof(Aluno));
if (a == NULL) return NULL;
printf("Entre proximo nome (. para terminar): ");
scanf(" %80[^\n]", a->nome);
/* Se no h um novo aluno, libera a memria alocada */
if (a->nome[0] == .) {
free(a);
return NULL;
}
printf("Entre matricula: ");
scanf(" %d", &(a->mat));
return a;
}

/* L os dados dos alunos da turma, um a um */


void lealunos(Aluno** v, int max) {
int n = 0;
while (n < max) {
v[n] = lealuno();
if (v[n] == NULL)
return;
n++;
}
}
/* Imprime os dados dos alunos da turma */
void imprimealunos(Aluno** v, int n) {
int i;
for (i = 0; i < n; i++)
if (v[i] != NULL) {
printf("nome: %s mat: %d\n", v[i]->nome, v[i]->mat);
}
}
/* Libera a memria alocada para as estruturas Aluno */
void liberaalunos(Aluno** v, int n) {
int i;
for (i = 0; i < n; i++)
if (v[i] != NULL)
free(v[i]);
}
int main(void) {
Aluno** alunos;
int max, n;
printf("Entre maximo de alunos: ");
scanf("%d",&max);
alunos = (Aluno**) malloc(max * sizeof(Aluno*));
if (alunos != NULL) {
for (n = 0; n < max; n++)
alunos[n] = NULL;
lealunos(alunos, max);
imprimealunos(alunos, max);
liberaalunos(alunos, max);
free(alunos);
}
return 0;
}
Adapte esse programa para implementar as seguintes funcionalidades:
7

(a) Escreva uma funo que receba um vetor de ponteiros para Aluno,
o tamanho mximo do vetor e um nmero de matrcula e remova
do vetor, se existir, o aluno cujo nmero de matrcula seja igual
matrcula especificada. A posio no vetor ocupada pelo aluno
removido deve receber o valor NULL. Assuma que o vetor de ponteiros
para Aluno pode conter buracos (ou seja, posies que armazenam o
valor NULL). A funo deve retornar 1, se o aluno foi removido, e 0,
caso no haja no vetor um aluno com o nmero de matrcula dado.
No esquea de liberar a rea alocada para o aluno removido. Essa
funo deve obedecer o seguinte prottipo:
int removealuno (Aluno** v, int n, int mat);
Insira na funo main testes para sua funo removealuno. Teste
pelo menos uma remoo para uma matrcula existente no vetor e
uma remoo para uma matrcula no existente no vetor. Aps a
chamada de removealuno imprima uma mensagem informando se o
aluno foi removido ou se no foi encontrado no vetor. Use tambm a
funo imprimealunos para exibir as informaes dos alunos antes e
depois da tentativa de remoo.
(b) Crie uma funo inserealuno que receba um vetor de ponteiros para
Aluno, o tamanho mximo do vetor, o nmero atual de alunos no
vetor e um ponteiro para uma estrutura Aluno e insere este novo
aluno no vetor de alunos, mantendo o vetor ordenado crescentemente
por matrcula. Para garantir a ordem do vetor de alunos, voc deve
verificar os nmeros de matrcula dos alunos existentes no vetor e, ao
encontrar a posio onde deve ser inserido o novo aluno, voc deve
empurrar os demais alunos uma posio para frente. Essa funo
deve obedecer o seguinte prottipo:
int inserealuno (Aluno** v, int tam, int n, Aluno* novo);
Os parmetros da funo so:

v o vetor de alunos;
tam o tamanho do vetor;
n o nmero de alunos no vetor;
novo um ponteiro para os dados do novo aluno.

Modifique a funo lealunos para que ela chame inserealuno para


inserir ordenadamente no vetor cada novo aluno lido. Teste novamente o seu programa. Entre dados no ordenados e verifique se o
vetor de alunos foi criado com os nmeros de matrcula corretamente
ordenados.
(c) Agora que o vetor de alunos criado de forma que os alunos estejam
ordenados por matrcula, modifique sua funo removealuno para
que no deixe buracos no vetor de alunos, ou seja, depois de remover
um aluno voc deve voltar uma posio no vetor cada aluno restante.
8

Tambm altere a funo removealuno para que no seja necessrio


percorrer todo o vetor quando a matrcula especificada no estiver
presente no vetor.
(d) Escreva uma funo exibeporintervalo que receba um vetor de
ponteiros para Aluno, o tamanho mximo do vetor e dois nmeros
de matrcula especificando um intervalo (ou seja, o primeiro nmero
de matrcula deve ser menor ou igual ao segundo) e exiba as informaes dos alunos com matrculas contidas nesse intervalo. Sua funo
deve necessariamente utilizar o fato do vetor estar ordenado crescentemente por nmeros de matrcula. Caso no haja nenhum aluno com
matrcula no intervalo especificado, a sua funo deve imprimir uma
mensagem como "No h alunos no intervalo especificado".

Você também pode gostar