PublicouJoaquim Marta Alterado mais de 4 anos atrás
Módulo III Módulo 3 Programação Estruturada Programação e Sistemas de Informação
2 Índice do módulo Noções Introdutórias Subprogramas Variáveis
Tipos de subprogramas Procedimentos Funções Variáveis Locais Globais Recursividade Bibliotecas
3 Módulo III Noções Introdutórias Como referido no módulo 1, uma das técnicas de resolução de problemas é a DECOMPOSIÇÃO. E uma das vantagens da linguagem C é o facto de permitir uma programação MODULAR. A programação modular permite-nos aplicar o conceito de decomposição. Programação e Sistemas de Informação
4 Noções Introdutórias Desde o primeiro programa em C que utilizamos funções: main() printf(….) scanf(….) system(…) abs(….) …. Reparem nos aspectos comuns…
5 Procedimentos e Funções
De acordo com o conceito da programação estruturada, a escrita de algoritmos (e programas) deve ser baseada no desenho modular dos mesmos.
6 Procedimentos e Funções
Imaginem o seguinte problema: Escreva um programa que coloque no ecrã o seguinte (mas utilizando estruturas de repetição): ******************** Números entre 1 e 5 1 2 3 4 5
7 Procedimentos e Funções
#include<stdio.h> main() { int i, numero; for(i=0;i<20;i++) /* 1ª linha de asteriscos */ printf("*"); printf("\nNumeros entre 1 e 5\n"); for(i=0;i<20;i++) /* 2ª linha de asteriscos */ for(i=1;i<=5;i++) /* números de 1 a 5 */ printf("\n%d\n",i); for(i=0;i<20;i++) /* asteriscos finais */ }
8 Procedimentos e Funções
No programa anterior repetimos a escrita de 20 asteriscos 3 vezes for(i=0;i<20;i++) printf("*"); Como evitar a repetição do mesmo código várias vezes?
9 Procedimentos e Funções
Aqui entram os conceitos de Procedimentos e Funções Embora ainda sem saber como escrever uma função, já as temos utilizado ao longo dos nossos programas: Exemplo: main(), printf(…), scanf(…), … De seguida podemos ver uma simplificação do programa anterior, através do uso de funções (procedimentos). Nota: mais adiante veremos qual a diferença entre procedimentos e funções.
#include<stdlib.h> asteriscos() /* função responsável pela escrita de 20 asteriscos */ { int i; for(i=0;i<20;i++) printf("*"); } main() asteriscos(); /* invocação da função asteriscos */ printf("\nNumeros entre 1 e 5\n"); for(i=1;i<=5;i++) printf("\n%d\n",i); system("pause");
11 Procedimentos e Funções
Um programa em C possui sempre a função main(), independentemente das restantes funções que possua. Um programa em C começa sempre a ser executado na função main(), mesmo que esta não esteja em primeiro lugar. O facto de termos várias funções num programa, não quer dizer que elas sejam executadas. Só serão executadas se forem invocadas ("chamadas") pela função main() ou por outra função invocada pela função main(). A invocação é feita escrevendo o nome da função com os respectivos (). Exemplo: asteriscos();
12 Procedimentos e Funções
Como funciona uma função: O código da função só é executado quando esta é invocada; Quando uma função é invocada o programa que a invoca é "suspenso" temporariamente. Em seguida são executadas as instruções da função. Quando a função terminar, o controlo de execução do programa volta ao local em que a função foi invocada. Pode receber parâmetros; Pode devolver um resultado.
13 Procedimentos e Funções
Sintaxe em C: nomeDaFuncao() { < bloco de instruções ; > }
14 Procedimentos e Funções
Sintaxe algorítmica: Função nomeDaFuncao() inicio < bloco de instruções > fimFunção
15 Procedimentos e Funções
Vantagens do uso de funções: Permite o reaproveitamento de código já escrito (por si ou por outros programadores); Evita que um trecho (pedaço) de código que seja repetido várias vezes dentro de um mesmo programa; Permite a alteração de um trecho de código de uma forma mais rápida. Com o uso de uma função é preciso alterar apenas dentro da função que se deseja; Permite que os blocos do programa não fiquem grandes demais e, por consequência, mais difíceis de entender ; Facilita a leitura do código fonte; Permite separar o programa em partes (blocos) que possam ser logicamente compreendidos de forma isolada.
16 Procedimentos e Funções
Características de uma função: Cada função tem de ter um nome único, que é usado para a sua invocação; Uma função pode ser invocada (chamada) a partir de outras funções; Uma função (como o seu nome deve indicar) deve realizar uma única tarefa bem definida; Uma função deve comportar-se como uma caixa negra, ou seja, não interessa como o faz, o que interessa é o resultado final; Uma função pode receber parâmetros; Uma função pode retornar para a função que a invocou, um valor como resultado do seu trabalho.
17 Procedimentos e Funções
Nome de uma função: Segue as mesmas regras dos nomes das variáveis; Tem de ser único no programa ( não pode ser igual ao nome de outra função ou variável); Deve ser de fácil leitura a através dele devemos conseguir perceber o que a função faz.
18 Funções – Parâmetros e Argumentos
+++++ ******* ********** Com a aplicação de funções, elabore um programa capaz de mostrar o output (mensagens) anteriores. Use também estruturas de repetição.
19 Esta seria até agora a melhor forma de resolução problema.
… void cinco_mais() { int i; for(i=0;i<5;i++) printf("+"); } void sete_asteriscos() for(i=0;i<7;i++) printf("*"); void dez_asteriscos() for(i=0;i<10;i++) main() { cinco_mais(); puts("\n"); sete_asteriscos(); dez_asteriscos(); puts("\n\n\n"); system("pause"); } Esta seria até agora a melhor forma de resolução problema. No entanto é possível simplificar a resolução
20 Funções – Parâmetros e Argumentos
Como podemos verificar no programa anterior, temos funções com código muito semelhante. Ex: sete_asteriscos(), dez_asteriscos() Estas funções apenas diferem no número de asteriscos que são impressos. Vejamos então o que podemos fazer para simplificar o programa anterior…
21 main() { cinco_mais(); puts("\n"); asteriscos(7); asteriscos(10);
#include<stdio.h> #include<stdlib.h> void cinco_mais() { int i; for(i=0;i<5;i++) printf("+"); } void asteriscos(int nr_asteriscos) for(i=0;i<nr_asteriscos;i++) printf("*"); main() { cinco_mais(); puts("\n"); asteriscos(7); asteriscos(10); puts("\n\n\n"); system("pause"); }
22 Funções – Parâmetros e Argumentos
Como podemos ver no código anterior, podemos enviar informação para as funções. main() { … asteriscos(10); } void asteriscos(int nr_asteriscos) ARGUMENTOS PARÂMETROS
23 Funções – Parâmetros e Argumentos
Características dos parâmetros e argumentos Os argumentos e parâmetros podem ser de qualquer tipo (int, float, char, …). Os parâmetros de uma função são separados por vírgula, e é obrigatória a indicação do tipo de cada parâmetro. Ex. void funcaoX(int par1, char par2, float par3) Ex. void funcaoX(int par1, par2, par3) ERRADO O nr. de argumentos enviados tem de ser igual ao nr. de parâmetros que vão receber os valores
24 Funções – Parâmetros e Argumentos
Características dos parâmetros e argumentos (cont.) Um parâmetro não é mais do que uma variável local à função a que pertence. Um parâmetro é automaticamente inicializado com o valor enviado pelo programa invocador. A passagem de argumentos para a função deve ser realizada colocando-os dentro de parêntesis, separados por vírgulas. Ex. funcaoX(1, 'a', media, 1.2); Os argumentos enviados podem ser valores (1, 'a') ou variáveis (valor1, letra, …).
25 Funções – Parâmetros e Argumentos
Características dos parâmetros e argumentos (cont.) O número de argumentos enviados para uma função deve ser igual ao número de parâmetros existentes no cabeçalho da função. Os tipos de dados têm também de ser iguais. Ex. main() { funcaoX('A', 123, 23.44); } funcaoX(char letra, int valor1, float numero)
26 Funções – Parâmetros e Argumentos
Voltando ao exercício inicial: +++++ ******* ********** Acham que se podia simplificar ainda mais???
#include<stdlib.h> void imprime_caracteres(int nr_asteriscos, char caracter_a_imprimir) { int i; for(i=0;i<nr_asteriscos;i++) printf("%c", caracter_a_imprimir); } main() { imprime_caracteres(5, '+'); puts("\n"); imprime_caracteres(7, '*'); imprime_caracteres(10, '*'); imprime_caracteres(5, '+'); puts("\n\n\n"); system("pause"); }
28 Funções – Instrução return
Esta instrução permite terminar a execução de uma função e voltar à função que a invocou. A execução da instrução return na função main() faz com que o programa termine. main() { imprime(); printf("ola"); } void imprime() { printf("impressão"); return; #include<stdio.h> printf("xau");
29 Funções – Instrução return
Mas além de terminar a função que está a ser executada pode também devolver (retornar) valores para o local onde foi invocada . E esta é a característica mais importante do return Se até agora consegue enviar valores para as funções invocadas (com argumentos e parâmetros), agora também já consegue devolver valores das funções invocadas para as funções invocadores.
30 Funções – Instrução return
Termina a função que está a ser executada Permite devolver um único valor (resultado) à função invocadora. Este valor poderá ser armazenado numa variável ou aproveitado por uma instrução. Sintaxe da instrução return return valor_de_retorno; ou return;
31 #include<stdio.h>
#include<stdlib.h> int funcao_soma(int valorA, int valorB) { int total; total=valorA+valorB; return total; } main() int valor1, valor2, soma; printf("\nIntroduza o valor 1: "); scanf("%d",&valor1); printf("\nIntroduza o valor 2: "); scanf("%d",&valor2); soma=funcao_soma(valor1, valor2); printf("\n\nSoma = %d \n", soma); system("pause");
32 A mesma funcionalidade do exercício anterior, mas mais simplificado…
#include<stdio.h> #include<stdlib.h> int funcao_soma(int valorA, int valorB) { return valorA+valorB; } main() int valor1, valor2; printf("\nIntroduza o valor 1: "); scanf("%d",&valor1); printf("\nIntroduza o valor 2: "); scanf("%d",&valor2); printf("\n\nSoma = %d \n", funcao_soma(valor1, valor2)); system("pause");
33 Funções – Instrução return
Notas: Uma função pode ser invocada dentro de outra função. funcao_soma(5, funcao_soma(3,2)); Uma função pode ter várias instruções return, mas apenas uma é realmente executada. … if (a==3) return 3; else return 1;
34 Funções – Instrução return
Notas (cont.) O facto de uma função retornar um valor não obriga a que esse valor tenha de ser aproveitado (armazenado) pala função invocadora. ERRADO: ..... funcao_soma(valor1, valor2)=soma;
35 Funções – Instrução return
int funcao_soma(int valorA, int valorB) { int total; total=valorA+valorB; return total; } O tipo de dados retornado tem de ser o mesmo tipo de dados definido para a função Temos sempre de indicar qual o tipo de dados que a nossa função vai retornar float funcao_multiplica (int x, int y) ….
36 Funções – Instrução return
Tipo de dados void Em C existe uma palavra reservada – void – que permite indicar que uma função não devolve qualquer tipo de dados. void funcao_xpto () { }
37 Funções – Protótipos das funções
Onde colocar as funções: Dentro de um mesmo ficheiro (por agora), antes ou depois da função main(). No entanto se as funções forem colocadas depois da função main, alguns compiladores geram erros ou alertas. Para evitar esses erros ou alertas usam-se os protótipos (cabeçalhos) de funções. Estes protótipos não são mais do que a primeira linha da função seguida de ponto e vírgula. int funcao_soma(int valorA, int valorB);
38 Funções – Protótipos das funções
Os protótipos das funções devem ser colocados depois da inclusão das bibliotecas. Não é necessário criar protótipo da função main().
39 Procedimentos e Funções
Qual a diferença entre Procedimentos e Funções? Procedimento: não devolve (retorna) qualquer valor à função que o invocou. Não tem a instrução "return" Função: devolve um valor de um determinado tipo à função invocadora. Possui a instrução "return"
40 Funções – Tipos de Variáveis
Variáveis LOCAIS: São declaradas dentro de uma função; São conhecidas apenas dentro da função onde estão declaradas. #include<stdio.h> main() { int var_local; var_local=2; func(); printf("%d\n",var_local); system("pause"); } func() var_local=127;
41 Funções – Tipos de Variáveis
Variáveis GLOBAIS: São declaradas fora das funções (normalmente após a inclusão das bibliotecas); São conhecidas em todas as funções do programa (o seu valor está sempre acessível) #include<stdio.h> int var_global; main() { var_global=10; func(); printf("%d\n",var_global); system("pause"); } func() var_global=var_global+20;
42 Funções – Tipos de Variáveis
Resumo Tipos de variáveis: Locais Globais Use sempre que possível variáveis locais para garantir a independência das funções. Não confundir tipos de Variáveis (locais e globais) com tipos de Dados (int, float, …)
43 Funções – Passagem de Parâmetros
A passagem de parâmetros consiste no envio de valores para as funções invocadas. Exemplo: funcaoX(10, 20); A passagem de parâmetros pode ser feita: Por Valor Por Referência
44 Funções – Passagem de Parâmetros
Passagem de parâmetros por valor É enviado o valor do argumento para a função; A função recebe esse valor no parâmetro definido, ou seja, a função fica com uma "cópia" valor original. É aquilo que tem vindo a ser feito até agora.
45 Funções – Passagem de Parâmetros
Passagem de parâmetros por valor #include<stdio.h> #include<stdlib.h> main() { int valor, res; valor=20; res=func(valor); printf("%d",res); system("pause"); } func(int valor_recebido) valor_recebido=valor_recebido+100; return valor_recebido; memória 001a 002b 003c 004d … valor  20 res  120 valor_recebido 20 120
46 Funções – Passagem de Parâmetros
Passagem de parâmetros por referência É enviado para a função o endereço de memória do(s) argumento(s). A função recebe nos parâmetros definidos os endereços de memória dos argumentos, ou seja, "a localização na memória" dos valores dos argumentos.
47 Funções – Passagem de Parâmetros
Passagem de parâmetros por referência #include<stdio.h> #include<stdlib.h> main() { int valor; valor=20; func(&valor); printf("%d",valor); system("pause"); } func(int *endereco_recebido) *endereco_recebido=*endereco_recebido+100; memória 001a 002b 003c 004d … valor  20 120 endereco_recebido  001a
48 Funções – Passagem de Parâmetros
Passagem de parâmetros por valor: São enviados valores para a função. São criadas cópias dos valores originais. Passagem de parâmetros por referência: São enviados endereços de memória para a função. "Trabalhamos" com os valores originais.
49 Funções - Recursividade
Consiste na capacidade de uma função se chamar (invocar) a ela própria. Verificamos que estamos perante código recursivo, quando dentro de uma função temos uma chamada a essa mesma função. Ex: funcao(int x) { … funcao(b); }
50 Funções - Recursividade
Problema: Desenvolva uma aplicação capaz de calcular o factorial de um número. Exemplo: Factorial de 4 = 4*3*2*1 = 24 Factorial de 5 = 5*4*3*2*1 = 120
51 Funções - Recursividade
#include <stdio.h> #include<stdlib.h> int factorial(int num) { int res=1, i; for (i=num; i>=1; i--) res = res * i; } return res; int main() int numero; printf("\n Factorial a calcular:"); scanf("%d", νmero); printf("\n Resultado: %d \n", factorial(numero)); system("pause"); SEM RECURSIVIDADE
52 Funções - Recursividade
No entanto se analisar melhor o problema factorial verifica que: Factorial de N = N * factorial de N-1 O factorial de N-1 = N-1 * factorial de (N-1)-1 … Até 1
53 Funções - Recursividade
Exemplo: factorial (fact) de 4: fact(4)=4*fact(3) fact(3)=3*fact(2) fact(2)=2*fact(1) fact(1)=1 24 6 2 1 A Recursividade funciona exactamente desta forma. Vamos de seguida implementar a solução recursiva em C.
54 Funções - Recursividade
#include <stdio.h> #include<stdlib.h> int factorial(int num) { int res; if (num==1) return 1; } else res=num*factorial(num-1); return res; int main() int numero; printf("\n Factorial a calcular:"); scanf("%d", νmero); printf("\n Resultado: %d \n", factorial(numero)); system("pause"); COM RECURSIVIDADE
55 Funções - Recursividade
Regras para a escrita de funções recursivas A primeira instrução de uma função recursiva deve ser sempre o critério de paragem (qual é a condição ou condições que se devem verificar para que a função pare de se invocar a si própria). Só depois de escrito o critério de paragem é que se deverá escrever a chamada recursiva da função, sempre relativa a um subconjunto. Vantagens da Recursividade: Menor quantidade de código escrito; Maior legibilidade (após a compreensão do conceito); Evita a escrita de estruturas de repetição. Desvantagens da Recursividade: Perda de performance (porque as funções ficam em "standby").