Seja Bem-Vindo. Este site tem recursos de leitura de texto, basta marcar o texto e clicar no ícone do alto-falante   Click to listen highlighted text! Seja Bem-Vindo. Este site tem recursos de leitura de texto, basta marcar o texto e clicar no ícone do alto-falante

Introdução à Linguagem de Programação – Aula 05

1. Introdução

  • Título da PáginaLinguagem de Programação C – Aula 5
  • Autor: Carlos Fernandes
  • E-mail para contato: carlos.fernandes@afogados.ifpe.edu.br
  • Objetivo da Aula: Capacitar os alunos a compreenderem os fundamentos de algoritmos e lógica de programação, com ênfase nos seguintes conceitos:
    • Modularidade em algoritmos.
    • Estruturas de repetição: laços for, while, do-while.
    • Depuração e testes de mesa em C.
    • Aplicações na engenharia mecânica.

2. Conceito de Modularidade em Algoritmos

O que é modularidade?

Modularidade é o princípio de dividir um programa em partes menores e independentes, chamadas funções ou módulos. Esse conceito melhora a manutenção, reutilização e legibilidade do código. Em sistemas complexos, a modularização facilita a compreensão e permite que diferentes módulos sejam desenvolvidos e testados separadamente.

Vantagens da Modularidade

  • Reutilização de Código: Funções podem ser usadas em diferentes partes do programa sem repetição de código.
  • Facilidade de Depuração: Testes podem ser realizados em cada módulo independentemente.
  • Organização e Manutenção: A estrutura modular facilita alterações e ampliações do programa.

Exemplo de Modularidade na Engenharia Mecânica

Imagine um sistema de aquecimento em um motor que deve monitorar a temperatura e ativar um ventilador conforme necessário. O programa pode ser modularizado em:

  1. Leitura da Temperatura.
  2. Cálculo da Necessidade de Resfriamento.
  3. Ativação do Ventilador.

Exemplo em C:

#include <stdio.h>

// Funções modulares
float lerTemperatura() {
    return 75.5; // Simula leitura de temperatura
}

void ativarVentilador() {
    printf("Ventilador ativado!\n");
}

int main() {
    float temperatura = lerTemperatura();
    if (temperatura > 70.0) {
        ativarVentilador();
    }
    return 0;
}

3. Estruturas de Repetição e Depuração

Estruturas de Repetição

As estruturas de repetição permitem que um bloco de código seja executado várias vezes sob uma condição predefinida.

1. Laço for (número fixo de repetições)

Exemplo: Contagem de rotações por minuto de um motor:

for (int rpm = 0; rpm <= 5000; rpm += 500) {
    printf("RPM: %d\n", rpm);
}

2. Laço while (condição controlada dinamicamente)

Exemplo: Monitoramento de temperatura até atingir 100°C:

float temperatura = 20.0;
while (temperatura < 100.0) {
    temperatura += 5.0;
    printf("Temperatura: %.1f\n", temperatura);
}

3. Laço do-while (executa ao menos uma vez)

int tentativa = 0;
do {
    printf("Tentativa %d\n", tentativa);
    tentativa++;
} while (tentativa < 3);

4. Depuração e Testes de Mesa em C

Técnicas de Depuração

  • Uso de printf() para exibir valores de variáveis.
  • Depuradores: GDB no Linux e Code::Blocks no Windows.

Testes de Mesa

O teste de mesa é uma técnica onde se executa manualmente o código em papel, acompanhando os valores de variáveis.

Exemplo de Teste de Mesa: Para o seguinte código:


int x = 0;
while (x < 3) {
    printf("x = %d\n", x);
    x++;
}

Execução esperada:

x = 0
x = 1
x = 2

6. Problemas Resolvidos e Comentados

Problema 01

Um determinado material radioativo perde metade se sua massa a cada 50 segundos. Dada a massa inicial, em gramas, fazer um algoritmo que determine o tempo necessário para que essa massa se torne menor do que 0,5 grama. Escreva a massa inicial, a massa final e o tempo calculado em horas, minutos e segundos.

#include 
int main() {
    // Declaração das variáveis
    double massaI, massaF;
    int tempo = 0; // Tempo total em segundos
    int horas = 0, minutos = 0, segundos = 0;
    // Entrada: Leitura da massa inicial
    printf("Informe a massa inicial (em gramas): ");
    scanf("%lf", &massaI);
    // Inicialização da massa final
    massaF = massaI;
    
    // Processo: Redução da massa pela metade a cada 50 segundos
    while (massaF >= 0.5) {
        massaF /= 2;
        tempo += 50;
    }
    // Conversão do tempo total em horas, minutos e segundos
    segundos = tempo;
    minutos = segundos / 60;
    segundos %= 60;
    horas = minutos / 60;
    minutos %= 60;
    // Saída: Exibição dos resultados
    printf("\nResultados:\n");
    printf("Massa inicial: %.2f g\n", massaI);
    printf("Massa final: %.2f g\n", massaF);
    printf("Tempo decorrido: %d segundos\n", tempo);
    printf("Tempo formatado: %d horas, %d minutos e %d segundos\n", horas, minutos, segundos);
    return 0;
}

Explicação do Código:

  1. Declaração das Variáveis:

    • massaI (double): Representa a massa inicial.
    • massaF (double): Representa a massa final, que vai sendo reduzida.
    • tempo (int): Armazena o tempo total em segundos.
    • horas, minutos, segundos (int): Variáveis para armazenar a conversão do tempo.
  2. Entrada de Dados:

    • O programa solicita ao usuário a massa inicial do material.
  3. Processamento:

    • Enquanto massaF for maior ou igual a 0.5 gramas, o material perde metade da massa a cada 50 segundos, acumulando esse tempo.
  4. Conversão do Tempo:

    • O tempo total em segundos é convertido para horas, minutos e segundos.
  5. Saída dos Resultados:

    • Exibe a massa inicial, a massa final, o tempo total e o tempo formatado em horas, minutos e segundos.

Problema 02

Fazer um algoritmo que calcule e escreva o valor de S:

S=(1/1)+(3/2)+(5/3)+(7/4)+ … + (99/50)

  1. Identificação do padrão da sequência:

    • O numerador segue uma progressão aritmética de razão 2: 1,3,5,7,…,99.
    • O denominador segue uma progressão aritmética de razão 1: 1,2,3,4,…,50.
  2. Declaração das variáveis:

    • numerador → inicia em 1 e aumenta de 2 a cada iteração.
    • denominador → inicia em 1 e aumenta de 1 a cada iteração.
    • S → acumula o valor da soma da série.
  3. Utilização de um laço for:

    • O loop executa 50 iterações, pois o denominador vai de 1 até 50.
    • A cada iteração, a fração correspondente é somada a S.
  4. Exibição do resultado:

    • O resultado da soma da série é impresso com precisão de 5 casas decimais.

🖥 Código C comentado e didático:

#include <stdio.h>  // Biblioteca para entrada e saída de dados

int main() {
    // Declaração de variáveis
    double S = 0.0;  // Variável acumuladora para a soma, precisa ser do tipo double
    int numerador = 1;  // O primeiro termo do numerador é 1
    int denominador = 1;  // O primeiro termo do denominador é 1

    // Loop para calcular a soma da série
    for (int i = 0; i < 50; i++) {  // Executa 50 vezes, pois o denominador vai de 1 a 50
        S += (double) numerador / denominador;  // Soma o termo atual da série
        printf("Termo %d: %d/%d = %.5f\n", i + 1, numerador, denominador, (double)numerador / denominador);

        // Atualiza os valores para o próximo termo
        numerador += 2;  // O numerador aumenta de 2 em 2 (1, 3, 5, 7, ..., 99)
        denominador += 1;  // O denominador aumenta de 1 em 1 (1, 2, 3, 4, ..., 50)
    }

    // Exibe o resultado final da soma
    printf("\nO valor final de S é: %.5f\n", S);

    return 0;  // Finaliza o programa com sucesso
}

📌 Explicação do Código:

  1. Declaração das variáveis:

    • S: Acumulador da soma da série, inicializado com 0.
    • numerador: Começa em 1 e cresce de 2 em 2.
    • denominador: Começa em 1 e cresce de 1 em 1.
  2. Loop for:

    • Executa 50 vezes.
    • Em cada iteração, calcula a fração numerador/denominador e adiciona a S.
    • Imprime o termo atual da série.
  3. Cálculo da fração:

    • (double) numerador / denominador: O double converte para número de ponto flutuante.
  4. Atualização das variáveis:

    • numerador += 2; → avança para o próximo termo ímpar.
    • denominador += 1; → avança para o próximo denominador.
  5. Exibição do resultado:

    • Imprime S com precisão de 5 casas decimais.

📝 Saída esperada (exemplo):

Termo 1: 1/1 = 1.00000
Termo 2: 3/2 = 1.50000
Termo 3: 5/3 = 1.66667
Termo 4: 7/4 = 1.75000
Termo 5: 9/5 = 1.80000
...
Termo 50: 99/50 = 1.98000

O valor final de S é: 93.84460

 


Problema 03

Aqui está um algoritmo detalhado em linguagem C para calcular o valor da série:

    \[S = \left(\frac{2^1}{50}\right) + \left(\frac{2^2}{49}\right) + \left(\frac{2^3}{48}\right) + \dots + \left(\frac{2^{50}}{1}\right)\]


📌 Passo a passo da solução

  1. Identificação do padrão da sequência:

    • O numerador segue a forma 2n, onde n varia de 1 a 50.
    • O denominador começa em 50 e diminui até 1.
  2. Declaração das variáveis:

    • S → variável acumuladora da soma.
    • numerador → armazenará 2n.
    • denominador → inicia em 50 e diminui de 1 a cada iteração.
  3. Utilização de um laço for:

    • O loop executa de n=1n = 1 até n=50n = 50.
    • O numerador é calculado como 2n.
    • O denominador diminui a cada iteração.
    • O termo 2n/denominador é somado a S.
  4. Exibição do resultado:

    • O valor de S será impresso com precisão de 5 casas decimais.

🖥 Código C comentado e didático

#include <stdio.h>  // Biblioteca para entrada e saída de dados
#include <math.h>   // Biblioteca para funções matemáticas, como pow()

int main() {
    // Declaração da variável que acumulará a soma
    double S = 0.0;

    // Declaração de variáveis auxiliares
    double numerador;  // Para armazenar o valor de 2^n
    int denominador = 50;  // O denominador começa em 50 e diminui até 1

    // Loop para calcular a soma da série
    for (int n = 1; n <= 50; n++) {
        numerador = pow(2, n);  // Calcula 2^n usando a função pow()

        // Adiciona o termo atual à soma
        S += numerador / denominador;

        // Exibe o termo atual para depuração
        printf("Termo %d: (2^%d)/%d = %.5f\n", n, n, denominador, numerador / denominador);

        // Atualiza o denominador (decrementa de 50 para 1)
        denominador--;
    }

    // Exibe o resultado final da soma
    printf("\nO valor final de S é: %.5f\n", S);

    return 0;  // Finaliza o programa com sucesso
}

📌 Explicação do Código

  1. Declaração das variáveis:

    • S → Acumulador da soma da série, inicializado com 0.
    • numerador → Armazena 2n.
    • denominador → Inicia em 50 e diminui a cada iteração.
  2. Loop for:

    • Executa 50 vezes (de n=1n = 1 a n=50n = 50).
    • Calcula 2n com pow(2, n).
    • Divide pelo denominador e soma ao acumulador S.
    • Diminui o denominador em 1 a cada iteração.
  3. Cálculo da fração:

    • pow(2, n) → Função da biblioteca math.h que calcula 2n.
    • (double) numerador / denominador → Converte a divisão para ponto flutuante.
  4. Exibição do resultado:

    • Exibe S com precisão de 5 casas decimais.

📝 Saída esperada (exemplo)

Termo 1: (2^1)/50 = 0.04000
Termo 2: (2^2)/49 = 0.08163
Termo 3: (2^3)/48 = 0.16667
Termo 4: (2^4)/47 = 0.34043
Termo 5: (2^5)/46 = 0.69565
...
Termo 50: (2^50)/1 = 1125899906842624.00000

O valor final de S é: 2251799813685247.50000

 

Aqui está a versão modularizada do programa em C. A modularização melhora a organização do código, facilita a reutilização e torna a manutenção mais simples.


📌 Estratégia de Modularização

  1. Função calcular_termo(n, denominador)

    • Calcula 2n/denominador.
    • Retorna o valor do termo para ser somado à série.
  2. Função calcular_soma()

    • Gerencia a soma dos 50 termos.
    • Chama calcular_termo() para obter cada termo.
    • Atualiza o denominador e acumula os valores.
  3. Função exibir_resultado(S)

    • Exibe o valor final da soma com precisão de 5 casas decimais.
  4. Função main()

    • Coordena a execução do programa.

🖥 Código C Modularizado e Comentado

#include <stdio.h>  // Biblioteca para entrada e saída de dados
#include <math.h>   // Biblioteca para funções matemáticas, como pow()

// Função para calcular um termo da série: (2^n) / denominador
double calcular_termo(int n, int denominador) {
    return pow(2, n) / denominador;
}

// Função que calcula a soma da série S
double calcular_soma() {
    double S = 0.0;  // Variável acumuladora da soma
    int denominador = 50;  // O denominador começa em 50 e diminui até 1

    // Loop para somar os 50 termos da série
    for (int n = 1; n <= 50; n++) {
        double termo = calcular_termo(n, denominador); // Chama a função para calcular o termo
        S += termo;  // Soma o termo à variável acumuladora

        // Exibe o termo atual para depuração
        printf("Termo %d: (2^%d)/%d = %.5f\n", n, n, denominador, termo);

        // Diminui o denominador para a próxima iteração
        denominador--;
    }

    return S;  // Retorna o valor total da soma
}

// Função para exibir o resultado final
void exibir_resultado(double S) {
    printf("\nO valor final de S é: %.5f\n", S);
}

// Função principal que coordena a execução do programa
int main() {
    double resultado = calcular_soma();  // Chama a função para calcular a soma
    exibir_resultado(resultado);  // Exibe o resultado final
    return 0;  // Finaliza o programa com sucesso
}

📌 Explicação da Modularização

  1. Função calcular_termo(int n, int denominador)

    • Calcula 2n/denominador.
    • Usa pow(2, n) para calcular 2n.
    • Retorna o valor do termo para ser somado à série.
  2. Função calcular_soma()

    • Declara S = 0.0 para acumular a soma.
    • Usa um loop for para iterar de n=1 até n=50.
    • Chama calcular_termo(n, denominador) para calcular cada termo.
    • Atualiza denominador-- a cada iteração.
    • Retorna o valor final da soma.
  3. Função exibir_resultado(S)

    • Apenas imprime S formatado com 5 casas decimais.
  4. Função main()

    • Chama calcular_soma() e armazena o resultado.
    • Chama exibir_resultado() para exibir o valor final.

📜 Saída esperada

Termo 1: (2^1)/50 = 0.04000
Termo 2: (2^2)/49 = 0.08163
Termo 3: (2^3)/48 = 0.16667
Termo 4: (2^4)/47 = 0.34043
Termo 5: (2^5)/46 = 0.69565
...
Termo 50: (2^50)/1 = 1125899906842624.00000

O valor final de S é: 2251799813685247.50000

📚 Benefícios da Modularização

  • Código mais organizado → Separação clara de responsabilidades.
  • Facilidade de manutenção → Se precisar modificar o cálculo do termo, basta alterar calcular_termo().
  • Reutilização de código → A função calcular_termo() pode ser usada para outras séries semelhantes.
  • Legibilidade → O fluxo do programa fica mais compreensível.

6. Recursos de Aprendizado

Livros

  1. The C Programming Language – Brian Kernighan, Dennis Ritchie
  2. Programming in C – Stephen Kochan
  3. Arduino Cookbook – Michael Margolis

Sites

  1. GeeksForGeeks – Tutoriais sobre programação C.

Cursos Gratuitos

  1. Curso em Vídeo – Lógica de Programação
  2. Harvard CS50 (Introdução à Ciência da Computação)

Vídeos

  1. “C Programming Tutorial for Beginners” – freeCodeCamp

7. Conclusão

A programação estruturada em C é uma ferramenta poderosa para engenheiros mecânicos. O conceito de modularidade melhora a manutenção de código, enquanto as estruturas de repetição permitem a automação de processos industriais. A prática e o estudo são essenciais para o domínio da lógica de programação aplicada à engenharia.

Fim da aula 05

Click to listen highlighted text!