Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


c-05 linguagem C, Notas de estudo de Engenharia Telemática

Logica de Programação e Algoritmos

Tipologia: Notas de estudo

Antes de 2010

Compartilhado em 26/11/2010

samuel-santos-22
samuel-santos-22 🇧🇷

4.6

(41)

262 documentos

1 / 6

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E
TECNOLOGIA DA PARAÍBA – CAMPUS CAMPINA GRANDE
CURSO: CURSO SUPERIOR DE TECNOLOGIA EM TELEMÁTICA
PERÍODO: P1 TURMA: N
DISCIPLINA: ALGORITMOS E LINGUAGEM DE PROGRAMAÇÃO
PROFESSOR: CÉSAR ROCHA VASCONCELOS SEMESTRE LETIVO
2009.2
Módulo 05 – USO DE SUB-ROTINAS EM C
1. TÓPICOS ABORDADOS
1. Uso de funções e procedimentos em C.
Conforme dito anteriormente, C é uma linguagem que segue o paradigma estruturado e, por isso, é
orientada a sub-rotinas. Ao usar tal paradigma, o desenvolvedor deve procurar decompor um
problema do mundo real em funções e procedimentos.
2. SUB-ALGORITMOS:
Você deve ter notado que, basicamente, os sub-algoritmos permitem dividir grandes tarefas de
computação em tarefas menores. Ademais, a criação de sub-algoritmos evita a repetição de código,
face que quando um bloco de código que está sendo (ou poderá ser) repetido é transformado num
sub-algoritmo, este último, então, será (ou poderá ser) facilmente chamado diversas vezes dentro do
programa. Toda a programação em C é baseada em funções (o próprio programa principal é uma
função: a função main() ). Além disso, a estrutura da linguagem é bastante simples e a boa parte das
operações é realizada por funções da biblioteca padrão.
2.1 Objetivos da modularização de sistemas
· Facilitar o desenvolvimento, leitura e entendimento dos algoritmos
· Quebrar o problema em pequenas partes gerenciáveis (meta-padrão: dividir para conquistar)
· Potencializar a manutenção dos algoritmos
· Diminuir o acoplamento
o Minimizar o uso de variáveis globais
o Priorizar o uso de variáveis locais
o Usar parâmetros para enviar e receber dados de um módulo
o Abstrair a funcionalidade de um sub-algoritmo
· Aumentar a funcionalidade
o Simplicidade: cada módulo deve realizar uma única tarefa específica
o Instruções de um módulo devem ser fortemente relacionadas (coesão)
o Documentação interna: objetivo do módulo, descrição dos parâmetros de entrada e
saída, etc.
2.2 Como modularizar?
Um bom começo é realizar o desenvolvimento top-down:
· Parte-se de uma descrição geral do algoritmo (descreva-o em passos gerais);
· Gradativa e sucessivamente, refina-se cada passo, dividindo-o em partes menores;
· A partir daí, deve-se atacar os detalhes de cada um dos sub-passos, criando novos
refinamentos (não há uma regra: desdobre aquilo que melhor lhe convier);
· Os sucessivos desdobramentos irão gerar pequenos trechos de código que delimitam poucos
contextos do problema que se está atacando;
pf3
pf4
pf5

Pré-visualização parcial do texto

Baixe c-05 linguagem C e outras Notas de estudo em PDF para Engenharia Telemática, somente na Docsity!

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E

TECNOLOGIA DA PARAÍBA – CAMPUS CAMPINA GRANDE

CURSO: CURSO SUPERIOR DE TECNOLOGIA EM TELEMÁTICA

PERÍODO: P1 TURMA: N

DISCIPLINA: ALGORITMOS E LINGUAGEM DE PROGRAMAÇÃO

PROFESSOR: CÉSAR ROCHA VASCONCELOS

SEMESTRE LETIVO

Módulo 05 – USO DE SUB-ROTINAS EM C

1. TÓPICOS ABORDADOS

1. Uso de funções e procedimentos em C.

Conforme dito anteriormente, C é uma linguagem que segue o paradigma estruturado e, por isso, é

orientada a sub-rotinas. Ao usar tal paradigma, o desenvolvedor deve procurar decompor um

problema do mundo real em funções e procedimentos.

2. SUB-ALGORITMOS:

Você já deve ter notado que, basicamente, os sub-algoritmos permitem dividir grandes tarefas de

computação em tarefas menores. Ademais, a criação de sub-algoritmos evita a repetição de código,

face que quando um bloco de código que está sendo (ou poderá ser) repetido é transformado num

sub-algoritmo, este último, então, será (ou poderá ser) facilmente chamado diversas vezes dentro do

programa. Toda a programação em C é baseada em funções (o próprio programa principal é uma

função: a função main() ). Além disso, a estrutura da linguagem é bastante simples e a boa parte das

operações é realizada por funções da biblioteca padrão.

2.1 Objetivos da modularização de sistemas

∑ Facilitar o desenvolvimento, leitura e entendimento dos algoritmos

∑ Quebrar o problema em pequenas partes gerenciáveis (meta-padrão: dividir para conquistar)

∑ Potencializar a manutenção dos algoritmos

∑ Diminuir o acoplamento

o Minimizar o uso de variáveis globais

o Priorizar o uso de variáveis locais

o Usar parâmetros para enviar e receber dados de um módulo

o Abstrair a funcionalidade de um sub-algoritmo

∑ Aumentar a funcionalidade

o Simplicidade: cada módulo deve realizar uma única tarefa específica

o Instruções de um módulo devem ser fortemente relacionadas (coesão)

o Documentação interna: objetivo do módulo, descrição dos parâmetros de entrada e

saída, etc.

2.2 Como modularizar?

Um bom começo é realizar o desenvolvimento top-down :

∑ Parte-se de uma descrição geral do algoritmo (descreva-o em passos gerais);

∑ Gradativa e sucessivamente, refina-se cada passo, dividindo-o em partes menores;

∑ A partir daí, deve-se atacar os detalhes de cada um dos sub-passos, criando novos

refinamentos (não há uma regra: desdobre aquilo que melhor lhe convier);

∑ Os sucessivos desdobramentos irão gerar pequenos trechos de código que delimitam poucos

contextos do problema que se está atacando;

∑ O desenvolvimento top-down permite uma boa integração dos módulos, uma vez que cada

módulo é desenvolvido quando já se sabe claramente o contexto onde ele vai atuar;

∑ Mas lembre-se: cada módulo deve ser validado (testado) independentemente dos demais;

Exemplo: um programa para calcular a média final do aluno baseada em três notas:

// top-down: passo 01 - identificação dos passos gerais...

#include <stdio.h>

void main(){

// capturar os dados do aluno

// calcular sua média final

// exibir algum resultado

}

// top-down: passo 02 – primeiros desdobramentos...

#include <stdio.h>

void main(){

// capturar os dados do aluno // ler um nome // ler a primeira nota // ler a segunda nota // ler a última nota

// calcular sua média final // somar as três notas e dividí-las por três

// exibir algum resultado // se média >= 6 emita aprovado (ou reprovado caso contrário) }

// top-down: passo 03 – a captura dos dados...

#include <stdio.h>

char nome[40]; float nota1, nota2, nota3;

void main(){

// capturar os dados do aluno // ler um nome printf( “Insira seu nome completo: ” ); gets( nome );

// ler a primeira nota printf( “Insira uma nota: ” ); scanf( “%f”, &nota1 );

// ler a segunda nota printf( “Insira uma nota: ” ); scanf( “%f”, &nota2 );

// ler a última nota printf( “Insira uma nota: ” ); scanf( “%f”, &nota3 );

Continuação do passo 03 na próxima página:

// exibir algum resultado // se média >= 6 emita aprovado (ou reprovado caso contrário) printf ( “\nAluno(a): %s”, nome ); printf ( “\nNotas parciais: [%.2f], [%.2f] e [%.2f]”, nota1, nota2, nota3 ); printf ( “\nMedia final: [%.2f]”, media ); printf ( “\nSituacao: %s”, media >= 6? “Aprovado” : “Recuperacao” ); }

2.3 Problemas com a abordagem anterior:

O desenvolvimento top-down foi utilizado, mas:

∑ O programa ficou grande demais. Existe apenas um super-algoritmo monolítico que é o

próprio programa principal!

∑ Há muitas repetições de passos (observe a leitura de cada nota)!

∑ Como toda a lógica do programa está em uma única sub-rotina, qualquer alteração no

programa gera riscos (o risco de, sem querer, mexer em algo que já estava funcionando);

∑ E se quiséssemos uma média com base em mais de três notas (ou até menos)?

∑ O programa não está coeso (o main é um “faz tudo”: exibe e captura dados, calcula média,

verifica a situação do aluno, etc.).

2.4 Modularizando o programa anterior

// top-down: passo 06 – modularização…

#include <stdio.h> #include <conio.h> #include <alloc.h>

// área contendo os protótipos das funcoes... char* getNome( void ); void getNotas( float *parciais, int qtdNotas); float calcularMedia( float *parciais, int qtdNotas ); void exibirResultados( char nome[], float parciais, int qtdNotas ); char verificarSituacao( float media );

int main (void){ // limpar a tela clrscr();

// capturar o nome char *nome = getNome();

// vou usar alocação dinâmica de memória para ficar interessante // também poderíamos ter colocado este código em uma sub-rotina int qtd = 0; printf( "\nQuantas notas deseja inserir?" ); scanf( "%d", &qtd );

float *parciais = NULL;

if( ( parciais = (float*) malloc( qtd * sizeof(float) ) ) == NULL ){ printf( “ERRO: nao ha memoria suficiente para armazenar as notas parciais!” ); return 1; }

// capturando notas getNotas( parciais, qtd );

// exibir resultados exibirResultados( nome, parciais, qtd );

// liberando memória alocada previamente free( parciais );

getch(); return 0; }

// função que captura o nome do(a) aluno(a) char* getNome( void ){ char *nome = “Sem nome”; printf( "\nInsira seu nome completo: " ); gets( nome ); return nome; }

// procedimento que captura as notas parciais void getNotas( float *parciais, int qtdNotas ){ for( register int k = 0; k < qtdNotas; k++ ){ printf( "\nInsira uma nota: " ); scanf("%f", &parciais[ k ] ); } }

// função que retorna a média aritmética com base nas parciais float calcularMedia( float *parciais, int qtdNotas ){ float acumulador = 0; for( register int k = 0; k < qtdNotas; k++ ) acumulador += parciais[ k ]; return acumulador / qtdNotas; }

// imprime todos os resultados do programa void exibirResultados( char nome[], float *parciais, int qtdNotas ){ printf( "\nAluno(a): %s", nome ); printf( "\nNotas parciais:" );

for( register int k = 0; k < qtdNotas; k++ ) printf( " [%.2f] ", parciais[ k ] );

printf( "\nMedia final: [%.2f]", calcularMedia( parciais, qtdNotas ) ); printf( "\nSituacao: %s", verificarSituacao( calcularMedia( parciais, qtdNotas ) ) ); }

// verifica a situacao atual do aluno com base em uma média char* verificarSituacao( float media ){ return media >=6? "Aprovado" : "Reprovado"; }

Neste exemplo, foi possível observar o uso de diversas sub-rotinas, não é? Até o próprio main , neste

programa, é uma função; sua única particularidade consiste em ser uma função automaticamente

executada após o programa ser carregado.

2.5 Algumas regras importantes:

∑ Perceba que os parâmetros de uma função ou procedimento devem ser listados não apenas

com seus respectivos tipos, mas entre os parênteses que seguem o nome da função (tanto no

protótipo quanto na sua implementação).

∑ Por outro lado, quando uma função não possui parâmetros, colocamos a palavra reservada

void entre os parênteses.

∑ Veja que C exige que se coloque o protótipo da sub-rotina antes desta ser chamada. O

protótipo de uma função consiste na repetição da linha de sua definição seguida do caractere

∑ Além de receber parâmetros, uma função pode ter um valor de retorno associado. No

exemplo acima, a função main e algumas outras, como calculaMedia , getNome , etc.

possuem valor de retorno. Entretanto, note que existem outras sub-rotinas que não possuem

valor de retorno associado; neste caso, colocamos a palavra void antes do nome da função,

indicando a ausência de um valor de retorno.

E se quiséssemos fazer isso para mais de um aluno?