1. Introdução
- Título da Página: Linguagem 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:
- Leitura da Temperatura.
- Cálculo da Necessidade de Resfriamento.
- 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 eCode::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:
-
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.
-
Entrada de Dados:
- O programa solicita ao usuário a massa inicial do material.
-
Processamento:
- Enquanto
massaF
for maior ou igual a 0.5 gramas, o material perde metade da massa a cada 50 segundos, acumulando esse tempo.
- Enquanto
-
Conversão do Tempo:
- O tempo total em segundos é convertido para horas, minutos e segundos.
-
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)
-
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.
-
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.
-
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
.
-
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:
-
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.
-
Loop
for
:- Executa 50 vezes.
- Em cada iteração, calcula a fração
numerador/denominador
e adiciona aS
. - Imprime o termo atual da série.
-
Cálculo da fração:
(double) numerador / denominador
: Odouble
converte para número de ponto flutuante.
-
Atualização das variáveis:
numerador += 2;
→ avança para o próximo termo ímpar.denominador += 1;
→ avança para o próximo denominador.
-
Exibição do resultado:
- Imprime
S
com precisão de 5 casas decimais.
- Imprime
📝 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:
📌 Passo a passo da solução
-
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.
-
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.
-
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 aS
.
-
Exibição do resultado:
- O valor de
S
será impresso com precisão de 5 casas decimais.
- O valor de
🖥 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
-
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.
-
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.
-
Cálculo da fração:
pow(2, n)
→ Função da bibliotecamath.h
que calcula 2n.(double) numerador / denominador
→ Converte a divisão para ponto flutuante.
-
Exibição do resultado:
- Exibe
S
com precisão de 5 casas decimais.
- Exibe
📝 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
-
Função
calcular_termo(n, denominador)
- Calcula 2n/denominador.
- Retorna o valor do termo para ser somado à série.
-
Função
calcular_soma()
- Gerencia a soma dos 50 termos.
- Chama
calcular_termo()
para obter cada termo. - Atualiza o denominador e acumula os valores.
-
Função
exibir_resultado(S)
- Exibe o valor final da soma com precisão de 5 casas decimais.
-
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
-
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.
-
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.
- Declara
-
Função
exibir_resultado(S)
- Apenas imprime
S
formatado com 5 casas decimais.
- Apenas imprime
-
Função
main()
- Chama
calcular_soma()
e armazena o resultado. - Chama
exibir_resultado()
para exibir o valor final.
- Chama
📜 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
- The C Programming Language – Brian Kernighan, Dennis Ritchie
- Programming in C – Stephen Kochan
- Arduino Cookbook – Michael Margolis
Sites
- GeeksForGeeks – Tutoriais sobre programação C.
Cursos Gratuitos
Vídeos
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