ISCTE, IGE, PROGRAMAÇÃO II


Ano lectivo de 1995/96 - Exame de 9 de Setembro de 1996 (segunda época)


Notas:

  1. A cotação completa de cada grupo/questão/alínea é indicada junto.
  2. O exame pode ser realizado com consulta.
  3. O grupo 1 será resolvido em papel (sem ligar o computador!).
  4. Os grupos 2 e 3 serão resolvidos no computador (depois de entregue o grupo 1!). Trabalhe na disquete e guarde os ficheiros com frequência.
  5. As respostas aos grupos 2 e 3 devem ser colocadas em ficheiros separados de nomes grupo2.c e grupo3.c.
  6. Não se esqueça de identificar a folha de exame, a disquete e, por meio de um cabeçalho (em comentário), cada um dos ficheiros.
  7. Tem 2:30h para resolver o exame.

[6,0] Grupo I

Teoria

Listagem 1:

int i = 1, a = 3, b = 1, aux;
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define ORDENA(a, b, aux) ((a) > (b) ? ((aux)=(a),(a)=(b),(b)=(aux)) : (b))

[2,0] 1. Supondo as definições da Listagem 1, qual o valor das seguintes expressões e que valor tomam as variáveis envolvidas depois do cálculo?
a) MAX(i++, 0)
b) MAX(i = b, a)
c) ORDENA(a, b, aux)

[2.0] 2.
a) Qual a diferença entre os ciclos while e do while?
b) Reescreva o seguinte fragmento de código de modo a usar o ciclo while:

int c;
do
{
    c = getchar();
    if(c != EOF)
	putchar(c);
}
while(c != EOF);

c) Reescreva o fragmento anterior usando um ciclo for.
d) Reescreva o seguinte fragmento de código de modo a usar o ciclo do while:

int n, valor = 13;
printf("Adivinhe:");
scanf("%d", &n);
while(n != valor)
{
    if(n > valor)
        printf("Muito grande!\nAdivinhe:");
    else if(n < valor)
        printf("Muito pequeno!\nAdivinhe:");
    scanf("%d", &n);
}
printf("Acertou!\n");

[2,0] 3. O que imprime a chamada func("Ola mundo!")?

void func(char *cadeia)
{
    if(*cadeia != '\0')
    {
        func(cadeia+1);
        putchar(*cadeia);
    }
}

[8,0] Grupo II

Programação - Listas

Admita o seguinte troço de código:

#include <stdlib.h>
#include <stdio.h>

typedef struct elemento
{
    int valor;
    struct elemento *proximo;
} Lelemento;

typedef struct
{
    unsigned long numero; /* numero de elementos na lista. */
    Lelemento *primeiro;
} Lista;

Lista *Lcria(void)
{
    Lista *l;

    if((l = malloc(sizeof(*l))) == 0)
	return 0;
    l->numero = 0;
    l->primeiro = NULL;
    return l;
}

[1,5] 1. Escreva uma função Lista *Linsere(Lista *l, int valor) que insira valor na lista l (num lugar arbitrário). Deve devolver a lista l ou NULL em caso de erro.

[5,5] 2. Escreva uma função Lista *Ltransfere(Lista *lista1, unsigned long i1, Lista *lista2, unsigned long i2, unsigned long quantos) que transfira quantos elementos da lista lista2, a partir do elemento i2 (inclusivé), para a lista lista1 imediatamente antes do elemento i1 (o primeiro elemento é o elemento zero). Para transferir os elementos para o final da lista lista1 especifica-se i1 = lista1->numero. Verifique se os valores i1, i2 e quantos são compatíveis com o tamanho de cada uma das listas! Deve devolver a lista lista1 ou NULL em caso de erro.

[1,0] 3. Escreva um programa que:
a) Vá inserindo valores inteiros pedidos ao utilizador em duas listas (as inserções em cada lista terminam com o primeiro valor negativo).
b) Imprima os valores em cada uma das listas.
c) Transfira elementos duma lista para outra, perguntando ao utilizador os locais de onde e para onde transferir e o número de elementos a tranferir.
d) Imprima os valores em cada uma das listas, de modo a poder-se verificar se a transferência foi correctamente efectuada.


[6,0] Grupo III

Programação - Recursividade, funções e ciclos

[1,0] 1. Escreva uma função recursiva double potencia(double x, unsigned n) que calcule a potência n de x.

[4,5] 2. Seja a sucessão x(k) definida recursivamente como x(k) = x(k-1) + (v/[x(k-1)]^(n-1)-x(k-1))/n e x(0)=1. É possível mostrar que o limite desta sucessão é a raiz n de v, ou seja v^(1/n). Escreva uma função double raiz(double v, unsigned n) que calcule, duma forma iterativa, a raiz n de v usando a fórmula recursiva indicada. Faça uso da função potência definida na questão 1. O cálculo da sucessão deve parar quando o valor absoluto do termo (v/[x(k-1)]^(n-1)-x(k-1))/n for inferior a uma tolerância (e.g. define TOL 1e-6).

Nota: A expressão a^b significa "potência b de a".

[0,5] 3. Faça um programa que teste a função acima, comparando os resultados de raiz(), chamada na forma raiz(v, n), com os da função pow() (da biblioteca padrão - incluir math.h), chamada na forma pow(v, 1.0/n).


Página concebida e mantida por Eng. Manuel Menezes de Sequeira (última actualização 2006/07/07)
Copyright © 1996-2001 ISCTE