ISCTE, IGE, PROGRAMAÇÃO II


Ano lectivo de 1995/96 - Resolução do exame de 9 de Setembro de 1996 (segunda época)


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