Grupo I
Teoria
1.a) MAX(i++, 0)=2 e i=3.
1.b) MAX(i = b, a)=3, a=3, b=1
e i=1.
1.c) ORDENA(a, b, aux)=3, a=1, b=3
e aux=3.
2.a) Tanto o ciclo while como o ciclo do
while executam uma instrução enquanto a expressão de
controlo tiver valor lógico verdadeiro. Mas no ciclo do
while a instrução é executada, a cada iteração, antes
da expressão de controlo ser avaliada, enquanto que no ciclo while
a instrução é executada depois da expressão
de controlo ser avaliada (e se tiver valor lógico verdadeiro,
bem entendido...). Assim, a instrução num ciclo do while
é executada sempre pelo menos uma vez, enquanto no ciclo while
pode não ser executada nenhuma vez.
2.b)
int c;
while((c = getchar()) != EOF)
putchar(c);
2.c)
int c;
for(c = getchar(); c != EOF; c = getchar())
putchar(c);
ou
int c;
for(; (c = getchar()) != EOF;)
putchar(c);
2.d)
int n, valor = 13;
do
{
printf("Adivinhe:");
scanf("%d", &n);
if(n > valor)
printf("Muito grande!\n");
else if(n < valor)
printf("Muito pequeno!\n");
}
while(n != valor);
printf("Acertou!\n");
3. A chamada func(4) imprime:
!odnum alO
Grupo II
Programação - Listas
1.
Lista *Linsere(Lista *l, int valor)
{
Lelemento *e;
if(l == NULL)
return NULL;
if((e = malloc(sizeof(*e))) == NULL)
return NULL;
e->valor = valor;
e->proximo = l->primeiro;
l->primeiro = e;
l->número++;
return l;
}
2.
Lista *Ltransfere(Lista *lista1, unsigned long i1,
Lista *lista2, unsigned long i2, unsigned long quantos)
{
unsigned long i;
Lelemento *el1, *el2i, *el2f, *aux;
if(lista2 == NULL || quantos == 0)
return lista1;
if(lista1 == NULL || i1 > lista1->número || i2 + quantos > lista2->número)
return NULL;
/*
* Retira troco da lista2:
* (Note-se que el2i comeca por apontar o elemento anterior ao primeiro
* a transferir, sendo depois ajustado para apontar o primeiro elemento
* a transferir!
*/
/* Procura troco da lista 2 a transferir: */
for(i=0, el2i = lista2->primeiro; i+1 < i2; i++, el2i = el2i->proximo)
;
for(el2f = el2i; i+1 < i2 + quantos; i++, el2f = el2f->proximo)
;
if(i2 == 0)
{ /* Retira troco do inicio da lista2: */
el2i = lista2->primeiro;
lista2->primeiro = el2f->proximo;
}
else
{ /* Retira troco do meio (ou final) da lista2: */
aux = el2i->proximo;
el2i->proximo = el2f->proximo;
el2i = aux;
}
lista2->número -= quantos; /* actualiza contador. */
/*
* Insere troco na lista1:
*/
if(i1 == 0)
{ /* Insere troco no inicio da lista1: */
el2f->proximo = lista1->primeiro;
lista1->primeiro = el2i;
}
else
{ /* Insere troco no meio (ou final) da lista2: */
/* Procura local de inserção na lista1: */
for(i=0, el1 = lista1->primeiro; i+1 < i1; i++, el1 = el1->proximo)
;
el2f->proximo = el1->proximo;
el1->proximo = el2i;
}
lista1->número += quantos; /* actualiza contador. */
return lista1;
}
3.
Lista *Limprime(Lista *l)
{
unsigned long i;
Lelemento *e;
if(l == NULL)
return NULL;
if(l->número == 0)
{
puts("\tLista vazia.");
return l;
}
for(i = 0, e = l->primeiro; e != NULL; i++, e = e->proximo)
printf("\tElemento %lu -> %d\n", i, e->valor);
return l;
}
int main(void)
{
int valor, para;
unsigned long i1, i2, q;
Lista *lista1, *lista2;
/* Cria listas: */
if((lista1 = Lcria()) == NULL || (lista2 = Lcria()) == NULL)
return EXIT_FAILURE;
puts("Valores para a lista 1 (até ao primeiro negativo):");
/* Insere lista1: */
while(scanf("%d", &valor), valor >= 0)
if(Linsere(lista1, valor) == NULL)
return EXIT_FAILURE;
puts("Valores para a lista 2 (até ao primeiro negativo):");
/* Insere lista2: */
while(scanf("%d", &valor), valor >= 0)
if(Linsere(lista2, valor) == NULL)
return EXIT_FAILURE;
/* Imprime listas: */
puts("Lista 1:");
if(Limprime(lista1) == NULL)
return EXIT_FAILURE;
puts("Lista 2:");
if(Limprime(lista2) == NULL)
return EXIT_FAILURE;
do
{
printf("Tranfere da lista ");
while(scanf("%d", ¶), para != 1 && para != 2)
;
printf("posição origem ");
scanf("%lu", &i2);
printf("posição destino ");
scanf("%lu", &i1);
printf("quantos? ");
scanf("%lu", &q);
/* Transfere: */
if(para == 1)
{
if(Ltransfere(lista2, i1, lista1, i2, q) == NULL)
puts("Erro na transferencia!");
}
else
if(Ltransfere(lista1, i1, lista2, i2, q) == NULL)
puts("Erro na transferencia!");
/* Imprime listas: */
puts("Lista 1:");
if(Limprime(lista1) == NULL)
return EXIT_FAILURE;
puts("Lista 2:");
if(Limprime(lista2) == NULL)
return EXIT_FAILURE;
printf("Para sair 0: ");
}
while(scanf("%d", &valor), valor != 0);
return EXIT_SUCCESS;
}
Grupo III
Programação - Recursividade, funções e ciclos
1.
double potencia(double x, unsigned n)
{
if(n == 0)
return 1.0;
else
return potencia(x, n-1) * x;
}
2.
double raiz(double valor, unsigned n)
{
double x, delta;
if(n == 0)
{
fprintf(stderr, "Raiz 0 não existe!\n");
return 0.0;
}
if(valor < 0 && n % 2 == 0)
{
fprintf(stderr, "Raiz %u dum valor negativo não existe!\n", n);
return 0.0;
}
x = 1.0;
do
{
x += delta = (valor / potencia(x, n-1) - x) / n;
printf("%g\n", x);
}
while(delta > TOL || delta < -TOL);
return x;
}
3.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define TOL 1e-6
double potencia(double x, unsigned n)
... /* ver acima */
double raiz(double valor, unsigned n)
... /* ver acima */
int main(void)
{
double x;
unsigned n;
printf("Raiz? ");
scanf("%u", &n);
printf("de? ");
scanf("%lg", &x);
if(n != 0 && (x >= 0 || n % 2 != 0))
{
printf("raiz(x, n) = %.12f\n", raiz(x, n));
if(x >= 0)
printf("pow(x, 1.0/n) = %.12f\n", pow(x, 1.0/n));
/* Afinal a nossa versão é melhor nalguma coisa... */
}
return EXIT_SUCCESS;
}
| Página
concebida e mantida por Eng. Manuel Menezes de Sequeira (última actualização 2006/07/07) Copyright © 1996-2001 ISCTE |
||||