Sei sulla pagina 1di 47

Módulos e Funções

Disciplina: Programação Básica


Professora: Cindy Fernandes

cindy.fernandes@unifesspa.edu.br ↔ cindystella@ufpa.br
Abordagem top-down

Modularizando algoritmos, na linguagem C com o uso de funções

Escopo de variáveis

Passagem de parâmetros

Introduziremos programação modular (programação estruturada)

Vantagens e funcionamento dos módulos


1. Abordagem top-down

• Conforme avançamos, aparecem problemas mais complexos e longos.


Isto faz com que a resolução destes se torne cada vez mais difícil.

• Abordagem com eficiência comprovada é a divisão de tarefas complexas


e longas em atividades mais simples e curtas.

• Essa abordagem é chamada top-down, pois se parte do topo, divide-se


em vários componentes menores e repete-se esse processo até o menor
componente.
1. Abordagem top-down

• Uma das vantagens da divisão das atividades é que muitas vezes a


solução para um problema menor pode ser reaproveitada na resolução
de diversos problemas maiores.

• Um exemplo: Cálculo da média aritmética de todas as turmas do ensino


médio de uma cidade.
1. Cálculo da média aritmética de uma turma.
2. Cálculo da média aritmética de uma escola
3. Cálculo da média aritmética de todas as escolas da cidade.
2. Modularizando Algoritmos
• A modularização de um algoritmo/programa é uma forma de dividir as
tarefas em subalgoritmos/ subprogramas. E cada um desses módulos
cuida de uma parte separada do problema.

• Cada módulo funciona semelhante a um programa, tendo, em geral,


entrada, processamento e saída.

• As entradas e saídas dos módulos são os meios pelos quais os módulos


interagem entre si.

• Ao criarmos um programa para resolver um determinado problema, uma


tarefa crítica é dividir o código grande em partes menores, fáceis de serem
compreendidas e mantidas.
2. Modularizando Algoritmos
• Na linguagem C, os módulos são as Funções
2. Modularizando Algoritmos
Funções
Em uma calculadora, quais são as suas 4 principais operações?
2. Modularizando Algoritmos
• Na linguagem C, os módulos são as Funções

Funções
São estruturas que agrupam um conjunto de comandos, que são executados
quando a função é chamada.
Exemplo:
scanf("%d", &x);

Funções
As funções podem retornar um valor ao final de sua execução.
Exemplo:
x = sqrt(4);
2. Modularizando Algoritmos
Por que utilizar funções?

• Evitar que os blocos do programa fiquem grandes demais e, por


consequência, mais difíceis de ler e entender.

• Separar o programa em partes que possam ser logicamente compreendidas,


de forma isolada.

• Permitir o reaproveitamento de código já construído (por você ou por


outros programadores).

• Evitar que um trecho de código seja repetido várias vezes dentro de um


mesmo programa, evitando inconsistências e facilitando alterações.
2. Modularizando Algoritmos
Definindo uma função

• Uma função é definida da seguinte forma:

tipo nome(tipo parâmetro1, ..., tipo parâmetroN) {


comandos;
return valor_de_retorno;
}

• Toda função deve ter um tipo que determina seu valor de retorno.

• Os parâmetros são variáveis que serão utilizadas pela função. Tais variáveis são
inicializadas com valores na chamada de execução da função.
2. Modularizando Algoritmos
Definindo uma função

• Tipos de retorno da função


• double, float, int, char, void, vetores e outros tipos
• Parâmetros da função
• Cada parâmetro é composto pelo tipo, nome e separados por vírgulas
• Retorno da função
• Quando uma função deve retornar um valor, devemos usar a palavra
reservada return seguido de um valor, variável ou operação do mesmo tipo
de retorno
• Corpo da função
• Código fonte com funcionalidade que a função deve executar
• Protótipo
• As funções possuem protótipos para definir sua estrutura
2. Modularizando Algoritmos
• Estrutura de uma Função
2. Modularizando Algoritmos
Exemplo de função

• A função abaixo soma dois valores, passados como parâmetros:

int soma(int a, int b) {


int c;
c = a + b;
return c;
}

• O valor de retorno deve ser do mesmo tipo definido para a função.

• Quando o comando return é executado, a função termina sua execução e retorna o valor
indicado para quem fez a chamada da função.
2. Modularizando Algoritmos
modulo1.c

A execução de um programa sempre


começa pela função main
2. Modularizando Algoritmos
modulo2.c , Uma função pode não ter parâmetros
2. Modularizando Algoritmos
2. Modularizando Algoritmos
Return

• Diz ao programa que o chamou que se retornou sem erro.

• Na linguagem C o zero significa false e o um significa true.

• Supondo um programa que chame uma rotina em C. A rotina executa e no final ela me
retorna um número. Para o meu programa que chamou essa rotina eu posso fazer uma
lógica baseada nesse retorno.

• Se o retorno for zero, sei que correu tudo bem e marco como sucesso, por exemplo.
• Se retornar 1, sabemos que deu erro.

• Podemos então notificar algum outro sistema ou chamar alguma outra rotina.

• Na teoria, qualquer número retornado diferente de zero é um retorno não esperado, ou


seja, um erro e poderá ser tratado, se for o caso
2. Modularizando Algoritmos
• Para que um módulo possa ser executado, precisa ser ativado ou chamado por um outro
módulo.

• Isso ocorre com todos os módulos do programa, com exceção do programa principal. É
sempre por esse módulo que o algoritmo inicia sua execução.

• O fluxo de execução de um algoritmo modularizado começa pelo módulo principal e é


desviado para qualquer outro módulo que seja ativado pelo módulo principal.

• Dentro desse módulo, pode haver chamada para outros módulos. Cada módulo que é
chamado é executado do início ao fim.

• Após seu término, o algoritmo prossegue do ponto em que o módulo foi chamado, ou
seja, do ponto da ativação.
2. Modularizando Algoritmos

Definindo funções depois do main

Até o momento, aprendemos que devemos definir as funções antes do


programa principal, mas o que ocorreria se declarássemos depois?
2. Modularizando Algoritmos

• Declarando funções depois do main

#include <stdio.h>
int main() {
float a = 0, b = 5;
printf("%f\n", soma(a, b));
return 0; Ocorrerá um erro de compilação, já que a
} função soma não foi definida antes do ponto
em que ela foi invocada.
float soma(float op1, float op2) {
return (op1 + op2);
}
2. Modularizando Algoritmos
Declarando uma função sem definí-la

• Para organizar melhor um programa e podermos implementar funções em partes


distintas do arquivo, protótipos de funções são utilizados.

• Protótipos de funções correspondem a primeira linha da definição de uma função


contendo tipo de retorno, nome da função, parâmetros e um ponto e vírgula.

tipo nome(tipo parâmetro1, ..., tipo parâmetro N);

• O protótipo de uma função deve vir sempre antes do seu uso.

• É comum colocar os protótipos de funções no inicio do arquivo do programa.


2. Modularizando Algoritmos
Protótipos de funções

#include <stdio.h>

float soma(float op1, float op2);

int main() {
float a = 0, b = 5;
printf("%f\n", soma(a, b));
return 0;
}

float soma(float op1, float op2) {


return (op1 + op2);
}
2. Modularizando Algoritmos

Exemplo

Escreva uma função na linguagem C que calcule o salário líquido de um funcionário.

O programa recebe através do teclado o salário bruto de um determinado funcionário,


• caso este seja inferior a R$ 900,00 é descontado 5% em impostos;
• se o salário variar de R$ 900,00 até R$1.800,00 é descontado 10% em impostos;
• se esse variar de R$1.800,00 a R$2.800,00 é descontado 15%;
• e se for superior a R$2.800,00 é descontado 20% em impostos.

Ao final a função deve exibir o salário líquido do funcionário.

Teste essa função em uma função main(), que lê o salário de N funcionários.


2. Modularizando Algoritmos

Exemplo

Na linguagem C, é necessário a declaração das interfaces, chamadas de


protótipos de funções no inicio do programa.

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

float calcularSalario (float salarioBruto);


2. Modularizando Algoritmos
int main(void) float calcularSalario (float salarioBruto)
{ {
float salarioLiquido; float total;
float salarioBruto; if (salarioBruto < 900) {
float total = salarioBruto - salarioBruto*5/100;
int i,n; return total;}
i=0;
printf("\n Fazer cálculo do salário de quantos funcionários ? \n");
if (salarioBruto >= 900 && salarioBruto <= 1800) {
scanf("%d",&n);
float total = salarioBruto - salarioBruto*10/100;
while ( i < n) {
return total;}
printf("\nInforme o valor do salario bruto R$: \n");
scanf("%f",&salarioBruto); if (salarioBruto > 1800 && salarioBruto <= 2800) {
float total = salarioBruto - salarioBruto*15/100;
salarioLiquido = calcularSalario (salarioBruto); return total;}

printf("\nO valor do salario liquido = R$ %f \n", salarioLiquido); if (salarioBruto >2800) {


float total = salarioBruto - salarioBruto*20/100;
i++; return total;}
} }
getch();
return 0;
}
2. Modularizando Algoritmos

• As entradas e saídas dos módulos são os meios pelos quais os módulos


interagem entre si.

• No exemplo modulos3.c a entrada é salarioBruto e a saída é


salarioLiquido.
2. Modularizando Algoritmos - Exercício
Faça um programa, na linguagem C, que terá quatro funções:

• calcular o fatorial de um número fornecido pelo usuário;


• Escrever a tabuada de multiplicação, sendo que o número da tabuada será
fornecida pelo usuário;
• Imprimir os valores do código ASCII* e;
• Calcular a média das notas dos alunos de uma turma, onde o número de
alunos e as notas são fornecidas pelo usuário.

A função main possui um menu que fica lendo caracteres e se o caractere for F,
chama a função do fatorial, se for T chama a função da tabuada, se for A chama
a função do código ASCII, se for M chama a função da média e se for qualquer
outro caractere, o programa é encerrado. (modulo4.c)
* ASCII é um código numérico usado para representar os caracteres
3. Escopo de variáveis
3. Escopo de variáveis

• Módulos podem ser considerados subprogramas. A idéia é que eles sejam


o mais independente entre si.

• Nesse sentido, é interessante que cada módulo possua suas próprias


variáveis, ficando a dependência dos módulos restrita basicamente à
interface (cabeçalho) do módulo.

• Poderemos ter duas situações:


• Variáveis globais.
• Variáveis locais.
3. Escopo de variáveis
3. Escopo de variáveis
3.1 Variáveis globais
• São declaradas antes de todos os módulos e podem ser manipuladas em qualquer
outro módulo.

• O inconveniente do uso de variáveis globais é a dependência que causa entre os


módulos.

• Como a variável pode ser acessada em qualquer módulo, uma alteração no valor dela
será vista em todos os outros módulos.

• Na manutenção de programas uma alteração em uma variável global pode ter efeitos
colaterais não previstos pelo programador, causando resultados indesejáveis.

• Usar variáveis globais não é boa prática de programação.


3. Escopo de variáveis
3.2 Variáveis locais
• As variáveis locais são definidas no início do módulo ao qual pertencem.

• Só podem ser acessadas dentro do módulo em que foram declaradas.

• O escopo da variável local prevalece sobre o escopo da variável global.

• O tempo de vida da variável local começa no início do módulo em que são


definidas e terminam no final do módulo. Assim, podemos ter variáveis
locais com o mesmo nome em módulos diferentes.
3. Escopo de variáveis
Podem existir variáveis locais e globais com o mesmo nome?
Sim. Caso isto ocorra, as variáveis irão se comportar como variáveis diferentes,
embora possuam o mesmo nome.

Nota: por uma questão de clareza na escrita do código, a prática de nomear


variáveis globais e locais com o mesmo nome não é recomendada.

Supondo que exista uma variável local e uma global com o mesmo nome, qual
prevalece?
Prevalece sempre a variável local.
As variáveis declaradas dentro da função main() são locais à mesma, pois embora
seja uma função especial main não deixa de ser uma função.
É muito comum programadores iniciantes confundirem as variáveis declaradas na
main() com variáveis globais. Isto é um erro conceitual. Para ser global a variável
tem que ser declarada fora do bloco de qualquer outra função, inclusive fora da
main().
4. Passagem de Parâmetros

• Um módulo pode receber valores que utilizará.

• Esses valores são parâmetros passados pelo módulo ativador e são


também chamados de argumentos.

• Podem ser: constantes, números, letras ou variáveis.

• Podem ser de dois tipos: por valor ou por referência.


5. Passagem de Parâmetros
5.1 Passagem de parâmetro por valor

• Uma cópia da variável é feita durante a ativação do módulo.

• Possíveis alterações na variável que sejam feitas no módulo


chamado não serão refletidas no módulo ativador.

• Na ativação do módulo, os argumentos devem ser passados


conforme os parâmetros foram declarados no cabeçalho do
módulo, na mesma ordem e obedecendo o mesmo tipo.
5. Passagem de Parâmetros
5.1 Passagem de parâmetro por valor - Exemplo
5. Passagem de Parâmetros
5.1 Passagem de parâmetro por valor - Exemplo

Exemplo de passagem por valor

modulo5.c, que possui duas funções:

1. float somatoria(int n), que retorna


resultado do somatório a seguir,
sendo n o parâmetro de entrada
do módulo: 5*i*i+ 2*i +8, com i
variando de 1 a n.

2. float pi (int n)
5. Passagem de Parâmetros
5.1 Passagem de parâmetro por valor - Exemplo

• Na passagem por valor,


apenas a própria função pode
alterar suas variáveis.

• Podemos observar que os


valores das variáveis a, b e c
não foram modificados na
função alterar.

• Como o tipo de passagem de


parâmetros é por valor foram
feitas apenas cópias dos
valores das variáveis a, b, e c
para as variáveis x, y e z.
5. Passagem de Parâmetros
5.2 Passagem de parâmetro por referência
5. Passagem de Parâmetros
5.2 Passagem de parâmetro por referência

• O endereço da variável e não uma cópia do valor é passado durante a


ativação do módulo.

• Possíveis alterações na variável que sejam feitas no módulo chamado


serão refletidas no módulo ativador.

• Deve ser usado quando mais de um valor deve ser retornado pelo
módulo.

Exemplo: modulo6.c
5. Passagem de Parâmetros
5.2 Passagem de parâmetro por referência
Exemplo:
5. Passagem de Parâmetros
5.2 Passagem de parâmetro por referência
• Em alguns casos pode ser
necessário criar uma função
que retorne mais de um
valor, ou que permita que as
outras funções alterem suas
variáveis. Nesses casos
utiliza-se a passagem por
referência e é fundamental o
uso de ponteiros.
5. Passagem de Parâmetros
6. Lista de Exercícios
1. São dadas as coordenadas (xc,yc) do centro de uma circunferência e a medida r de seu
raio. Também são dadas as coordenadas (x,y) de uma série de pontos, sendo que o último
deles é igual ao centro. Determine quantos pontos desta série estão dentro da
circunferência, quantos estão fora e quantos estão sobre ela. Crie a função dist(x1,y1,x2,y2)
que dá a distância entre os pontos (x1,y1) e (x2,y2) e, depois, utilize-a num programa que
resolva o problema proposto.

2. Escreva uma função CALCULA que:


receba como parâmetros duas variáveis inteiras, X e Y;
retorne em X a soma de X e Y;
retorne em Y a subtração de X e Y.
Pergunta: a passagem dos parâmetros para a função deve ser por valor ou por referência?
6. Lista de Exercícios
3. Codifique a função dv(n) que recebe um número n e devolve o seu dígito verificador.
Essa função deve implementar o seguinte método:

Suponha n= 345702159.
1. calculamos s = 3*10 + 4*9 + 5*8 + 7*7 + 0*6 + 2*5 + 1*4 + 5*3 + 9*2 = 202.
2. calculamos x = 11 − s%11 = 11 − 202%11 = 11 − 4 = 7.
3. O dígito verificador é 0 se x>9 e é o próprio x, caso contrário. Então, d= 7.
4. Codifique a função cpf(n,d) que devolve verdade só se o CPF não tem dígito
verificador d.
Use o método descrito no exercício anterior para calcular o dígito verificador do CPF do
seguinte modo:
Suponha CPF =345702159.
1. calculamos o primeiro dígito a = dv(345702159) = 7.
2. calculamos o segundo dígito b = dv(3457021597) = 1.
Então, número completo do CPF é 345702159−71.
6. Lista de Exercícios
3. Codifique a função dv(n) que recebe um número n e devolve o seu dígito verificador. Essa
função deve implementar o seguinte método:

Suponha n= 3457021597.
1. calculamos s = 3*11 + 4*10 + 5*9 + 7*8 + 0*7 + 2*6 + 1*5 + 5*4 + 9*3 +7*2= 252.
2. calculamos x = 11 − s%11 = 11 − 252%11 = 11 − 10 = 1. //segundo digito
3. O dígito verificador é 0 se x>9 e é o próprio x, caso contrário. Então, d= 1.
4. Codifique a função cpf(n,d) que devolve verdade só se o CPF não tem dígito
verificador d.
Use o método descrito no exercício anterior para calcular o dígito verificador do CPF do
seguinte modo:
Suponha CPF =345702159.
1. calculamos o primeiro dígito a = dv(345702159) = 7.
2. calculamos o segundo dígito b = dv(3457021597) = 1.
Então, número completo do CPF é 345702159−71.
6. Lista de Exercícios

Potrebbero piacerti anche