ISCTE, IGE, PROGRAMAÇÃO I


Ano lectivo de 1996/97 - Resolução do Exame de 18 de Julho de 1997


PARTE I

1.

int procura(int m[], int n, int o_que)
{
    int i;
    for(i = 0; i < n; i++)
	if(m[i] == o_que)
	    return 1;
    return 0;
}

2.

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


int main(void)
{
    int c, c_ant = ' ';

    while((c = getchar()) != EOF)
    {
	/*
	 * islower(c): corrente e' minuscula.
	 * !isalnum(c): anterior nao e' letra nem digito.
	 */
	if(islower(c) && !isalnum(c_ant))
	    c = toupper(c); /* converte para maiuscula. */
	putchar(c);
	c_ant = c;
    }

    return EXIT_SUCCESS;
}

3.

/*
 * Para simplificar considerou-se qualquer caracter != '0' como
 * o digito '1'. Ignorou-se o problema (importante!) de saber se
 * o valor e' representavel num unsigned long.
 */
unsigned long converteBinarioDecimal(const char binario[])
{
    unsigned long n = 0;
    while(*binario != '\0')
	n = 2 * n + (*binario++ != '0');
    return n;
}

PARTE II (8 valores)

4.

Versão A:

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

typedef enum {Nao, Sim} Logico;

int main(void)
{
    FILE *entrada, *saida;
    Logico dentro;
    int c, c_ant;

    if((entrada = fopen("entrada", "r")) == NULL)
	return EXIT_FAILURE;
    if((saida = fopen("saida", "w")) == NULL)
    {
	fclose(entrada);
	return EXIT_FAILURE;
    }

    dentro = Nao;
    c_ant = ' ';
    while((c = fgetc(entrada)) != EOF)
	if(dentro)
	    if(c_ant == '*' && c == '/')
	    {
		dentro = Nao;
		c_ant = ' '; /* para nao usar o '/' no inicio dum novo comentario */
	    }
	    else
		c_ant = c;
	else
	    if(c_ant == '/' && c == '*')
	    {
		fputc(' ', saida);
		dentro = Sim;
		c_ant = ' '; /* para nao usar o '*' no fim do novo comentario */
	    }
	    else
	    {
		/* O '/' nao pode ser escrito imediatamente, pois pode
		   ser o inicio dum comentario. So' e' escrito quando
		   se le o caracter seguinte e se verifica nao ser '*': */
		if(c_ant == '/')
		    fputc('/', saida);
		if(c != '/')
		    fputc(c, saida);
		c_ant = c;
	    }

    /* Pode ter ficado um '/' `a espera: */
    if(!dentro && c_ant == '/')
	fputc('/', saida);

    fclose(entrada);
    fclose(saida);

    return EXIT_SUCCESS;
}

Versão B (sugerida por várias resoluções dos alunos):

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

int main(void)
{
    FILE *entrada, *saida;
    int c, c_ant;

    if((entrada = fopen("entrada", "r")) == NULL)
	return EXIT_FAILURE;
    if((saida = fopen("saida", "w")) == NULL)
    {
	fclose(entrada);
	return EXIT_FAILURE;
    }

    c_ant = ' ';
    while((c = fgetc(entrada)) != EOF)
	if(c_ant == '/' && c == '*')
	{
	    fputc(' ', saida);
	    c_ant = ' '; /* para nao usar o '*' no fim do novo comentario */
	    while((c = fgetc(entrada)) != EOF && (c != '/' || c_ant != '*'))
		c_ant = c;
	    if(c == EOF)
	    {
		fprintf(stderr, "Aviso: comentario inacabado!\n");
		fclose(entrada);
		fclose(saida);
		return EXIT_SUCCESS;
	    }
	}
	else
	{
	    /* Um '/' nao pode ser escrito imediatamente, pois pode
	       ser o inicio dum comentario. So' e' escrito quando
	       se le o caracter seguinte e se verifica nao ser '*': */
	    if(c_ant == '/')
		fputc('/', saida);
	    if(c != '/')
		fputc(c, saida);
	    c_ant = c;
	}

    /* Pode ter ficado um '/' `a espera: */
    if(c_ant == '/')
	fputc('/', saida);

    fclose(entrada);
    fclose(saida);
    return EXIT_SUCCESS;
}

5.

#include <string.h>

/*
 * Para simplificar considerou-se qualquer caracter != '0' como
 * o digito '1'!
 */
void somaBinario(char r[], const char a[], const char b[])
{
    int ir, ia, ib;
    int e_vao = 0;

    /* Fazer a soma colocando o resultado, invertido, em r: */
    ir = 0;
    ia = strlen(a) - 1;
    ib = strlen(b) - 1;
    for( ; ia >= 0 || ib >= 0; ir++, ia--, ib--)
    {
	int soma = e_vao + 
	    (ia >= 0 ? a[ia] != '0' : 0) + 
	    (ib >= 0 ? b[ib] != '0' : 0);
	r[ir] = "01"[soma % 2];
	e_vao = soma / 2;
    }

    /* Faltou algum transporte? */
    if(e_vao > 0)
	r[ir++] = '1'; 
    else
    {
	/* Se nao houve transporte, o resultado pode conter zeros `a
	   esquerda (neste caso `a direita): */
        do ir--; while(ir >= 0 && r[ir] == '0');
	
	/* Incrementar para ir ser o local a colocar o '\0': */
	ir++;

	/* Se a cadeia vai ficar vazia, colocar um unico '0': */
        if(ir == 0)
	    r[ir++] = '0';
    }
    r[ir] = '\0';

    /* Inverter a cadeia de resultado: */
    for(ia = 0; ia < ir / 2; ia++)
    {
	char aux = r[ia];
	r[ia] = r[ir - ia - 1];
	r[ir - ia - 1] = aux;
    }
}

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