490 likes | 574 Views
Profs.:. José Eustáquio Rangel de Queiroz Roberto Medeiros de Faria. Carga Horária:. 60 h. Introdução à Programação. Capítulo 5. Funções. Introdução à Programação. Tópicos 5.1 Introdução 5.2 Módulos de Programas em C 5.3 Biblioteca de Funções Matemáticas 5.4 Funções
E N D
Profs.: José Eustáquio Rangel de Queiroz Roberto Medeiros de Faria Carga Horária: 60 h Introdução à Programação Capítulo 5 Funções
Introdução à Programação Tópicos 5.1 Introdução 5.2 Módulos de Programas em C 5.3 Biblioteca de Funções Matemáticas 5.4 Funções 5.5 Definições de Função 5.6 Protótipos de Funções 5.7 Arquivos de Cabeçalho 5.8 Chamada de Funções por Valor e por Referência 5.9 Geração de Números Aleatórios 5.10 Exemplo: Jogo de Azar
Introdução à Programação Tópicos 5.11 Classes de Armazenamento 5.12 Regras de Escopo 5.13 Recursividade 5.14 Exemplo de Recursividade: Série de Fibonacci 5.15 Recursividade vs. Iteração
5.1 Introdução • Divisão para a conquista • Construção de programas a partir de partes ou componentes menores • Módulos • Maior facilidade de gestão de cada módulo do que do programa original
5.2 Módulos de Programas em C • Funções • Módulos em C • Possibilidade de combinação de funções definidas pelo usuário com funções das bibliotecas nos programas • Existência de uma vasta gama de funções na biblioteca padrão de C
5.2 Módulos de Programas em C • Chamadas de Funções • Invocação de funções • Explicitação do nome da função e passagem de argumentos (dados) • Realização de operações ou manipulações pela função • Retorno dos resultados pela função
5.2 Módulos de Programas em C • Chamadas de Funções • Analogia • Solicitação de execução de uma tarefa pelo patrão a um empregado • Aquisição de informações sobre a tarefa pelo empregado • Execução da tarefa • Retorno dos resultados • Ocultação da informação (patrão não conhece os detalhes)
5.3 Biblioteca de Funções Matemáticas • Biblioteca de Funções Matemáticas • Execução de cálculos matemáticos comuns • #include <math.h> • Formato para a chamada de funções • Nome_da_Função(argumento1, …, argumentoN); • Uso da vígula como separador em listas múltiplas de argumentos
5.3 Biblioteca de Funções Matemáticas • Formato para a chamada de funções • printf( "%.2f", sqrt( 900.0 ) ); • Chamada da função sqrt, a qual retorna a raiz quadrada de seu argumento • Todas as funções matemáticas retornam dados do tipo double • Argumentos Constantes, variáveis ou expressões
5.4 Funções • Funções • Modularização de um programa • Todas as variáveis declaradas dentro de funções são variáveis locais • Conhecidas apenas no contexto da função • Parâmetros • Informação da comunicação entre funções • Variáveis locais
5.4 Funções • Benefícios de funções • Divisão para conquista • Desenvolvimento gerenciável de programas • Reusabilidade de Software • Uso de funções existentes como blocos para a construção de novos programas • Abstração • Ocultação de detalhes internos (funções da biblioteca) • Repetição de código evitada
5.5 Definições de Funções • Formato de Definição de uma Função Tipo_do_valor_de_retorno nome_da_função (lista de parâmetros ) { declarações e atribuições } • Nome_da_função Qualquer identificador válido
5.5 Definições de Funções • Formato de Definição de uma Função • Lista_de_Parâmetros Declaração de uma série de parametros • Um tipo deve ser listado explicitamente para cada parâmetro, caso contrário o parâmetro será considerado do tipo int
5.5 Definições de Funções • Formato de Definição de uma Função Tipo_do_valor_de_retorno nome_da_função (lista de parâmetros ) { declarações e atribuições } • Declarações e atribuições Corpo da função (bloco de código) • Variáveis podem ser declaradas dentro dos blocos (podem ser aninhadas) • Funções não podem ser definidas dentro de outras funções
5.5 Definições de Funções • Formato de Definição de uma Função • Retorno do Controle • Quando não há retorno return; • Se algo for retornado returnexpression;
5.5 Definições de Funções • Função Principal (Programa Principal) 01/* Determinação do máximo de três inteiros */ 02#include<stdio.h> 03 04intmaximo(int,int,int);/* protótipo da função */ 05intmain() 06{ 07inta, b, c; 08 09printf( “Digite três inteiros: " ); 10scanf( "%d%d%d", &a, &b, &c ); 11printf( “O maximo eh: %d\n", maximo( a, b, c ) ); 12 13return0; 14}
15/* Definição da função maximo */ 16 intmaximo(intx,inty,intz ) 17 { 18intmax = x; 19 20if( y > max ) 21max = y; 22 23 if( z > max ) 24 max = z; 25 26returnmax; 27} 5.5 Definições de Funções • Função Máximo Digite três inteiros: 22 85 17 Maximo eh: 85
5.6 Protótipos de Funções • Protótipo de uma Função • Nome da função • Parâmetros O QUE a função recebe • Tipo de Retorno Tipo de dado que a função retorna (defaultint) • Uso no processo de validação de funções • Necessidade de inclusão do protótipo apenas se a definição da função sucede a função principal • Função com o protótipo int maximo(int, int, int); • Recebimento de 3 parâmetros int • Retorno de 1 dado int
5.6 Protótipos de Funções • Coerção de Argumentos • Imposição de argumentos do tipo apropriado • Exemplo • Função sqrt Possibilidade de chamada com um argumento int, embora o protótipo em math.h especifique um argumento double • printf(“%.3f\n”, sqrt(4)); • Resultado gerado Cálculo correto de sqrt(4) e impressão do valor 2.000
5.6 Protótipos de Funções • Regras de Promoção • Especificação de como alguns tipos podem ser convertidos para outros sem perda de dados • Possibilidade de cometimento de erros • Conversão de double em int Truncamento da parte fracionária do valor double • Aplicação automática a expressões contendo dois ou mais tipos de dados (mistas)
5.7 Arquivos de Cabeçalho • Arquivos de Cabeçalho • Contêm os protótipos das funções das bibliotecas referenciadas no programa • E.g. <stdlib.h> , <math.h> , <conio.h> • Necessidade de inclusão da(s) linha(s) • #include <nome_do_arquivo> #include <math.h>
5.7 Arquivos-Cabeçalhos • Arquivos-Cabeçalhos Customizados • Criação de arquivos com funções • Salvamento • <nome_do_arquivo.h> • Inclusão em outros arquivos • #include“nome_do_arquivo.h” • Reuso das funções
5.8 Chamada de Funções por Valor e por Referência • Uso na invocação de funções • Chamada por valor • Cópia do(s) argumento(s) passado(s) para a função • Alterações do(s) argumento(s) na função não exercem influência sobre o(s) valor(es) original(ais) • Uso quando não há necessidade de alteração do argumento pela função • Prevenção contra alterações acidentais
5.8 Chamada de Funções por Valor e por Referência • Chamada por referência • Passagem do(s) argumento(s) original(ais) • Alterações do(s) argumento(s) na função implicam alterações no(s) original(ais) • Uso apenas com funções confiáveis que precisem modificar a variável original • Foco atual Chamada por valor
5.9 Geração de Números Aleatórios • Funçãorand • Inclusão de <stdlib.h> • Retorno de um número “aleatório” entre 0 and RAND_MAX (pelo menos 32767) i = rand(); • Pseudo-aleatoriedade • Seqüência pré-definida de números “aleatórios” • Mesma seqüência para qualquer chamada à função
5.9 Geração de Números Aleatórios • Ajuste de Escala • Obtenção de um número aleatório entre 1 e n 1 + ( rand() % n ) • rand() % n retorna um número entre 1 e n-1 • Adição de 1 para gerar um número aleatório entre 1 e n 1 + ( rand() % 6) • Número entre 1 e 6
5.9 Geração de Números Aleatórios • Funçãosrand • Inclusão de <stdlib.h> • Definição de uma “semente” (seed) inteira e deslocamento de sua seqüência “aleatória” para aquela locação srand( seed ); • srand( time( NULL ) );// inclusão de <time.h> • time( NULL ) • Retorno do tempo no qual o program foi compilado (em segundos) • “Aleatorização" da semente
5.9 Geração de Números Aleatórios 01Programa para randomização no lançamento de um dado */ 02#include<stdlib.h> 03#include<stdio.h> 04 05intmain() 06{ 07inti; 08unsignedsemente; Digite a semente: 67 6 1 4 6 2 1 6 1 6 4 09 10printf( “Digite a semente: " ); 11scanf( "%u", &semente ); 12srand(semente); 13for( i = 1; i <= 10; i++ ) { 14printf( "%10d", 1 + ( rand() % 6 ) ); 15if( i % 5 == 0 ) 16printf( "\n" ); Digite a semente:867 2 4 6 1 6 1 1 3 6 2 17} 18return0; 19}
5.10 Exemplo: Jogo de Azar • Simulador de Craps • Regras • Lançamento de dois dados • 7 ou 11 na primeira rodada, o jogador vence • 2, 3 ou 12 na primeira rodada (craps), o jogador perde (i.e. a casa vence) • 4, 5, 6, 8, 9 ou 10 na primeira rodada, a soma torna-se o “ponto” do jogador • Jogador ganhará se continuar lançando os dados até fazer seu ponto e isto ocorrer antes de obter 7 como resultado
5.10 Exemplo: Jogo de Azar 01/* Simulador de Craps */ 02#include<stdio.h> 03#include<stdlib.h> 04#include<time.h> 05 06introla_dados( void ); 07 08intmain() 09{ 10intplacar, soma, ponto; 11 12srand( time( NULL ) ); 13sum = rola_dados();/* primeiro lançamento dos dados */ 14switch( soma ) { 15case7:case11:/* ganha na primeira rodada */ 16placar = 1; 17break; 18case2:case3:case12:/* perdena primeira rodada */ 19placar = 2; 20break; 21default: /* armazena ponto */ 22placar = 0; 23ponto = soma; 24printf( “O total de pontos eh %d\n", ponto ); 25break; 26} 27while(placar == 0) {/* continua jogando */ 28soma = rola_dados();
5.10 Exemplo: Jogo de Azar 29 if(soma == ponto)/* vence fazendo ponto */ 30 placar = 1; 31else 32if(soma == 7)/* perde obtendo o valor 7 */ 33placar= 2; O jogador lançou 1 + 3 = 4 O total de pontos eh 4 O jogador lançou 1 + 4 = 5 O jogador lançou5 + 4 = 9 O jogador lançou5 + 6 = 10 O jogador lançou6 + 3 = 9 O jogador lançou1 + 2 = 3 O jogador lançou5 + 2 = 7 O jogador perdeu 34} O jogador lançou 4 + 6 = 10 O total de pontos eh 10 O jogador lançou 2 + 4 = 6 O jogador lançou6 + 5 = 11 O jogador lançou3 + 3 = 6 O jogador lançou6 + 4 = 10 O jogador venceu 35if(placar == 1) 36printf( “O jogador venceu\n" ); 37else 38printf( " O jogador perdeu\n " ); 39return0; 40} 41introla_dados(void) 42{ 43intdado1, dado2, soma; 44dado1 = 1 + ( rand() % 6 ); 45dado2 = 1 + ( rand() % 6 ); 46soma = dado1 + dado2; 47printf( “O jogador lançou %d + %d = %d vezes\n", dado1, dado2, soma ); 48returnsoma; 49} O jogador lançou 6 + 6 = 12 O jogadorvenceu O jogador lançou 6 + 5 = 11 O jogadorvenceu
5.11 Classes de Armazenamento • Especificadores de classes de armazenamento • Tempo (ou duração) de Armazenamento Período durante o qual o identificador permanece na memória • Escopo Local no qual o objeto pode ser referenciado no programa • Linkage (ligação) Especificação dos arquivos nos quais um identificador é conhecido
5.11 Classes de Armazenamento • Armazenamento Automático • Criação do objeto quando o bloco no qual é declarado for acionado • Existência do objeto enquanto o bloco estiver ativo • Destruição do objeto quando o bloco for descartado • auto Default para variáveis locais auto double x, y; • register Tentativa de conservação de uma variável em um registrador de alta velocidade • Uso apenas para variáveis automáticas register int counter = 1;
5.11 Classes de Armazenamento • Armazenamento Estático • Existência das variáveis durante toda a execução do programa • Valor default: zero • static Variáveis locais definidas em funções • Manutenção do valor após o término da função • Conhecimento apenas pela própria função • externDefault para variáveis globais e nomes de funções • Conhecimento por qualquer função
5.12 Regras de Escopo • Escopo de Arquivo • Identificador definido fora da função, conhecido por todas as funções • Uso para variáveis globais, definições de funções, protótipos de funções • Escopo de Função • Referência possível apenas dentro do corpo de uma função • Uso apenas para rótulos (start:, case:, etc.)
5.12 Regras de Escopo • Escopo de Bloco • Declaração de um identificador dentro do bloco • Início do escopo do bloco na declaração • Término do escopo do bloco na chave direita • Uso para variáveis e parâmetros de funções (variáveis locais de funções ) • “Ocultação“ de blocos exteriores dos blocos interiores se houver variáveis como nomes iguais em ambos os blocos • Escopo de Protótipo de Função • Uso para identificadores em listas de parâmetros
5.12 Regras de Escopo 01/* Exemplo de escopo */ 02#include<stdio.h> 03voida(void);/* protótipo da função a */ 04voidb(void);/* protótipo da função b */ 05voidc(void); /* protótipo da função c */ 06intx = 1;/* variável global */ 07intmain() 08{ 09intx = 5;/* variável local para main */ 10 printf("local x in outer scope of main is %d\n", x ); 11 { /* início de um novo escopo */ 12intx = 7; 13printf( "local x in inner scope of main is %d\n", x ); 14}/* término do novo escopo */ 15printf( "local x in outer scope of main is %d\n", x ); 16a();/* a contém x local automática */ 17b();/* b contém x local estática*/ 18c();/* c usa x global */ 19a();/* a reinicializa x local automática */ 20b();/* x local estática mantém seu valor anterior */ 21c();/* x global também mantém seu valor */ 22printf( "local x in main is %d\n", x ); 23return0; 24}
5.12 Regras de Escopo 25voida(void) 26{ 27intx = 25;/* inicializada a cada vez em que a é chamada */ 28printf( "\nx local em a eh %d após digitar a\n", x ); 29++x; 30printf( "x local em a eh %d antes de liberar a\n", x ); 31} 32voidb(void) 33{ 34static intx = 50;/* inicializa somente na primeira vez em que b é chamada */ 35printf( "\nx local estática eh %d ao digitar b\n", x ); 36++x; 37printf( " x local estática eh %d ao liberar b\n", x ); 38} 39voidc(void) 40{ 41printf( "\n x global eh %d ao digitar c\n", x ); 42x *= 10; 43printf( " x global eh %d ao liberar c\n", x ); 44}
5.12 Regras de Escopo local x in outer scope of main is 5 local x in inner scope of main is 7 local x in outer scope of main is 5 local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 50 on entering b local static x is 51 on exiting b global x is 1 on entering c global x is 10 on exiting c local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 51 on entering b local static x is 52 on exiting b global x is 10 on entering c global x is 100 on exiting c local x in main is 5
5.13 Recursividade • Funções Recursivas • Auto-chamadas • Possibilidade de solução apenas de um caso básico • Fragmentação de um problema em • O que é possível fazer • O quenãoé possível fazer • Necessidade de tal parte do problema se assemelhe ao problema original (versão mais simples ou menor) • Função Chamada a uma nova cópia de si própria (chamada recursiva ou etapa de recursão) para a solução do que não é possível fazer
5.13 Recursividade • Funções Recursivas • Caso básico eventualmente solucionado • Extensão, processamento e solução do problema como um todo
5.13 Recursividade • Exemplo • Fatoriais • 5! = 5 * 4 * 3 * 2 * 1 • Importante observar que • 5! = 5 * 4! • 4! = 4 * 3!... • Possibilidade de computação recursiva de factoriais • Solução do caso básico (1!=0!=1) e extensão para • 2! = 2 * 1! = 2 * 1 = 2; • 3! = 3 * 2! = 3 * 2 = 6;
5.14 Exemplo de Uso de Recursividade: Série de Fibonacci • Série de Fibonacci (0, 1, 1, 2, 3, 5, 8...) • Cada número é a soma dos dois anteriores • Possibilidade de solução recursiva • fib( n ) = fib( n - 1 ) + fib( n – 2 ) • Código para a função fibonacci long fibonacci( long n ) { if (n == 0 || n == 1) // caso básico return n; else return fibonacci(n – 1) + fibonacci(n – 2); }
5.14 Exemplo de Uso de Recursividade: Série de Fibonacci • Série de chamadas recursivas à função fibonacci f(3) f(1) f(2) return + f(0) f(1) return 1 return + return 1 return 0
5.14 Exemplo de Uso de Recursividade: Série de Fibonacci 01/* Função recursiva da Série de Fibonacci */ 02#include<stdio.h> 03 04longfibonacci(long); 05intmain() 06{ 07longresultado, numero; 08 09printf(“Digite um inteiro: "); 10scanf( "%ld", &numero ); 11resultado = fibonacci(numero); 12printf("Fibonacci( %ld ) = %ld\n", numero, resultado); 13return0; 14} 15/* Definição recursiva da função fibonacci */ 16longfibonacci(longn) 17{ 18if(n == 0 || n == 1) 19returnn; 20else 21returnfibonacci(n - 1) + fibonacci(n - 2); 22 }
5.14 Exemplo de Uso de Recursividade: Série de Fibonacci • Exemplo de Saída Digite um inteiro: 2 Fibonacci(2) = 1 Digite um inteiro : 3 Fibonacci(3) = 2 Digite um inteiro : 4 Fibonacci(4) = 3 Digite um inteiro : 5 Fibonacci(5) = 5 Digite um inteiro : 6 Fibonacci(6) = 8 Digite um inteiro : 10 Fibonacci(10) = 55 Digite um inteiro : 20 Fibonacci(20) = 6765 Digite um inteiro : 30 Fibonacci(30) = 832040
5.15 Recursividade vs. Iteração • Repetição • Iteração Laço explícito • Recursividade Chamadas repetidas à função • Terminação • Iteração Falha na condição do laço • Recursividade Reconhecimento do casobásico • Iteração/Recursividade Possibilidade de laços infinitos
5.15 Recursividade vs. Iteração • Ponto de Equilíbrio • Ponderação entre desempenho (iteração) e qualidade da engenharia de software (recursividade )
José Eustáquio Rangel de Queiroz Roberto Medeiros de Faria UNIVERSIDADE FEDERAL DE CAMPINA GRANDE CENTRO DE CIÊNCIAS E TECNOLOGIA DEPARTAMENTO DE SISTEMAS E COMPUTAÇÃO