Linguagens e Ambientes de Programação (2022/2023)



Prática 06

Primeiros exercícios sobre a linguagem C. Exercícios de 31 a 35.



Guião para usar a linguagem C na consola

  1. Usar um editor de texto qualquer para escrever um ficheiro "test.c"
  2. Gravar
  3. cc -std=c11 -o test test.c
  4. ./test
No caso do programa chamar funções da biblioteca "math", por exemplo a função sqrt ou exp, então é preciso compilar desta forma:

Guião para usar a linguagem C dentro do Eclipse

  1. Ativar Eclipse, escrevendo "eclipse" num consola.
  2. Window > Open Perspective... mudar perspetiva para C/C++
  3. File > New > C/C++ Project...
  4. Selecionar "C Managed Build"
  5. Escrever "Test" e selecionar "Hello World ANSI C Project" e "Linux GCC"
  6. Fazer "Finish" (ignorar o "Next")
  7. File > New > Source File
  8. Dar o nome "Test.c" ao ficheiro
  9. Escrever o programa no ficheiro "Test.c"
  10. Ctrl-S (save) para gravar
  11. Carregar seta branca e verde da barra de tools para compilar e correr o programa.
  12. Se o programa não correr logo, ir ao menu "Project", forçar um build manual (comando "Build Project"), e depois mandar o programa correr na seta verde. Trata-se dum bug antigo...

Instalação: Já está instalado nos laboratórios. Para instalar no seu computador pessoal, primeiro veja se o gcc está instalado. Se não estiver, dê o comando sudo apt install gcc make. Depois use o comando do Eclipse "Help>Install New Software...". Na caixa "Work with:" insira o p2 software repository correto para a sua versão do Eclipse. Depois selecione e instale apenas "CDT Main features". [Estas instruções são para o Linux. Noutros sistemas, a instalação do C poderá ser um pouco complicada. No caso do Windows, tente isto (não testado).]


  • 31 - Considere a seguinte variável global x e as seguintes funções f e g: Suponha que f e g são usadas num segmento de programa da seguinte forma:

    Quais os valores que ficam em s1 e s2, assumindo que os operandos nas expressões são avaliados da esquerda para a direita. Note que, em geral, os compiladores têm a liberdade de definir a ordem de avaliação ou seja a ordem de avaliação das subexpressões está indefinida ao nível da linguagem. Isso recomenda que evitemos escrever código do género do que está contido neste exemplo.


  • 32 - Analise o programa incompleto abaixo. No início, define-se um tipo Byte para representar bytes de memória. Também se define um tipo Block para representar sequências de bytes em memória. A função blockZero inicializa um bloco com zeros, e a função blockPrint mostra o conteúdo dum bloco.

    Pedimos-lhe para completar as funções blockFill_char_uint_double e blockPrint_char_uint_double.

    A função blockFill_char_uint_double guarda no início dum bloco três valores de diferentes tipos, sem qualquer alinhamento: um char, um unsigned int e um double.

    A função blockPrint_char_uint_double extrai e imprime (um por linha) três valores do início dum bloco, com os tipos: char, um unsigned int e um double.

    A função main já está escrita e serve para testar se você escreveu bem as funções anteriores.


  • 33 - Escreva em C um programa introspetivo que olhe para a sua própria pilha de execução e escreva os dados necessários para poder responder às seguintes perguntas: Registo de ativação é uma porção da pilha de execução que guarda os dados duma ativação de função, concretamente os argumentos, as variáveis locais, o endereço de retorno, etc. (Em inglês diz-se "activation record" ou "stack frame")

    Use o seguinte código como ponto de partida. Vai precisar de usar um apontador.


  • 34 - Considere o tipo Shape apresentado no exercício 9 da aula prática 1. Como é que definiria esse tipo em C, tentando capturar o conceito do tipo abstrato "Shape", que representa uma forma geométrica geral.

    O problema já está parcialmente resolvido e estude o código abaixo, especialmente o tipo "Shape".

    No código abaixo, também se oferece um construtor de pontos e um construtor de linhas.


  • 35 - Desenvolva um pequeno programa em C que escreva no ecrã um sucessão crescente de valores reais que aumente exponencialmente.

    Depois execute o programa e observe o aparecimento de valor real expecial inf.

    Explicação: Uma variável real tem uma capacidade limitada relativamente à magnitude dos valores representáveis. Mas existem estes três valores especiais: inf -inf nan. O primeiro representa infinito, o segundo representa menos infinito, e o terceiro significa not a number. O valor nan é gerado quando se tenta efetuar uma operação com argumentos inválidos, por exemplo, uma divisão de zero por zero. A linguagem C suporta especificamente o standard da indústria: IEEE 754.


  • 36 - Desenvolva um pequeno programa em C que mostre que as contas feitas com números reais podem não ser absolutamente exatas. Os valores reais com que trabalhamos são normalmente aproximações.

    Sugestão: Tome o valor 1.0/3.0 = 0.3333333..., decomponha-o em 100 partes, adicione as 100 partes. Será que assim conseguimos reconstituir o valor 1.0/3.0.

    Discussão: Quando trabalhamos com números reais temos de tomar em consideração o problema da inexatidão dos reais e em muitas situações não nos interessa usar a operação de igualdade. É melhor testar se o valor está a uma distância muito pequena (digamos a menos de 0.00000000001) do valor a comparar. Outra questão que vale a pena referir: as quatro operações básicas dos reais (+ - * /) são mais exatas do que as operações da biblioteca math.h. Por exemplo, para se obter o quadrado dum número real x, a forma certa é x*x e jamais pow(x,2). Se o problema se resolver de forma simples usando as operações aritméticas básicas, então devemos evitar as funções de biblioteca.



    Vídeos antigos

    Estes vídeos poderão estar um pouco desatualizados, pois foram feitos no contexto duma edição anterior do LAP. Contudo, partes dos vídeos poderão continuar a ter alguma utilidade.