[email protected] DSC/CCT/UFCG Profs.: José Eustáquio Rangel de Queiroz Roberto Medeiros de Faria Ulrich Schiel Carga Horária: 60 h DSC/CCT/UFCG Introdução à Programação [email protected] [email protected] Tópicos 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 Introdução Módulos de Programas em C Biblioteca de Funções Matemáticas Funções Definições de Função Protótipos de Funções Arquivos de Cabeçalho Chamada de Funções por Valor e por Referência Geração de Números Aleatórios Exemplo: Jogo de Azar 2 DSC/CCT/UFCG Introdução à Programação [email protected] [email protected] Tópicos 5.11 5.12 5.13 5.14 5.15 Classes de Armazenamento Regras de Escopo Recursividade Exemplo de Recursividade: Série de Fibonacci Recursividade vs. Iteração 3 5.1 Introdução DSC/CCT/UFCG Divisão para a conquista Construção de programas a partir de partes ou componentes menores [email protected] [email protected] Módulos Maior facilidade de gestão de cada módulo do que do programa original Componentes do programa que se repetem em pontos distintos 4 5.2 Módulos de Programas em C DSC/CCT/UFCG [email protected] [email protected] 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 5.2 Módulos de Programas em C DSC/CCT/UFCG Chamadas de Funções [email protected] [email protected] 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 6 5.2 Módulos de Programas em C DSC/CCT/UFCG Chamadas de Funções Analogia [email protected] [email protected] 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) 7 5.3 Biblioteca de Funções Matemáticas DSC/CCT/UFCG Biblioteca de Funções Matemáticas Execução #include de cálculos matemáticos comuns <math.h> [email protected] [email protected] Formato para a chamada de funções Nome_da_Função(argumento1, …, argumentoN); Uso da vígula como separador múltiplas de argumentos em listas 8 5.3 Biblioteca de Funções Matemáticas DSC/CCT/UFCG Formato para a chamada de funções [email protected] [email protected] 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 expressões Constantes, variáveis ou 9 5.4 Funções DSC/CCT/UFCG [email protected] [email protected] Funções Modularização de um programa Todas as variáveis declaradas funções são variáveis locais dentro de Conhecidas apenas no contexto da função Parâmetros Informação da comunicação entre funções Variáveis locais 10 5.4 Funções DSC/CCT/UFCG Benefícios de funções Divisão para conquista [email protected] [email protected] 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 11 DSC/CCT/UFCG 5.5 Definições de Funções [email protected] [email protected] 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 válido Qualquer identificador 12 5.5 Definições de Funções DSC/CCT/UFCG Formato de Definição de uma Função [email protected] [email protected] 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 13 5.5 Definições de Funções DSC/CCT/UFCG [email protected] [email protected] 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 14 5.5 Definições de Funções DSC/CCT/UFCG Formato de Definição de uma Função Retorno do Controle Quando não há retorno [email protected] [email protected] return; Se algo for retornado return expression; 15 5.5 Definições de Funções DSC/CCT/UFCG [email protected] [email protected] Função Principal (Programa Principal) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 /* Determinação do máximo de três inteiros */ #include <stdio.h> int maximo( int, int, int ); /* protótipo da função */ int main() { int a, b, c; printf( “Digite três inteiros: " ); scanf( "%d%d%d", &a, &b, &c ); printf( “O maximo eh: %d\n", maximo( a, b, c ) ); return 0; } 16 5.5 Definições de Funções DSC/CCT/UFCG [email protected] [email protected] Função Máximo 15 16 17 18 19 20 21 22 23 24 25 26 27 /* Definição da função maximo */ int maximo( int x, int y, int z ) { int max = x; if ( y > max ) max = y; if ( z > max ) max = z; return max; } Digite três inteiros: 22 85 17 Maximo eh: 85 17 DSC/CCT/UFCG 5.5 Definições de Funções [email protected] [email protected] /* Este programa lê nome e notas de alunos e determina a média da turma e o melhor aluno */ #include <stdio.h> #include <string.h> #include <conio.h> void lerdados(); char nome[20]=""; float nota; int main() { char melhor_aluno[20]=""; int contador; float media, melhor_nota, soma; /* INICIALIZACAO */ soma = 0; contador = 0; lerdados(); /* chamada da função */ /* PROCESSAMENTO */ melhor_nota = nota; strcpy(melhor_aluno, nome); while (nota != -1) {soma = soma+nota; contador = contador + 1; lerdados(); /* chamada da função */ if (nota > melhor_nota) {melhor_nota = nota; strcpy(melhor_aluno, nome); } } /* FINALIZACAO */ if (contador != 0) {media = soma / contador; printf("\nA media da turma e: %.2f\n", media); printf("O melhor aluno eh: %s", melhor_aluno); printf(" com a nota %.2f", melhor_nota); } else printf("\nNenhum aluno digitado."); getch(); return 0; } void lerdados() { printf("Digite o nome do proximo aluno: "); scanf("%s", &nome); printf("\nDigite a nota deste aluno: "); scanf("%f", ¬a); return; } 18 5.6 Protótipos de Funções DSC/CCT/UFCG Protótipo de uma Função Nome da função Parâmetros O QUE a função recebe de Retorno Tipo de dado que a função retorna (default int) [email protected] [email protected] Tipo 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 Retorno de 3 parâmetros int de 1 dado int 19 5.6 Protótipos de Funções DSC/CCT/UFCG Coerção de Argumentos Imposição de argumentos do tipo apropriado Exemplo [email protected] [email protected] 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)); gerado Cálculo correto de sqrt(4) e impressão do valor 2.000 Resultado 20 5.6 Protótipos de Funções DSC/CCT/UFCG [email protected] [email protected] 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) 21 5.7 Arquivos de Cabeçalho DSC/CCT/UFCG Arquivos de Cabeçalho [email protected] [email protected] 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> 22 5.7 Arquivos-Cabeçalhos DSC/CCT/UFCG Arquivos-Cabeçalhos Customizados Criação de arquivos com funções Salvamento [email protected] [email protected] Inclusão em outros arquivos <nome_do_arquivo.h> #include “nome_do_arquivo.h” Reuso das funções 23 5.7 Arquivos-Cabeçalhos DSC/CCT/UFCG void formapal(int n) { char letra[1], palavra[20]; int cont; [email protected] [email protected] /* inicializa‡ao */ strcpy(palavra,""); /* Processamento */ for(cont=1;cont<=n;cont++) { printf("Digite uma letra minusculas: "); scanf("%s", &letra); strcat(palavra, letra); } /* Finaliza‡ao */ printf("\nA palavra e:** %s**\n ", palavra); return; } /* Programa que forma várias palavras de tamanho variável a partir de letras digitadas */ #include <stdio.h> #include <string.h> #include "formapal.h" main() { int tamanho; /* inicializa‡ao */ printf("\nDigite o tamanho da primeira palavra \n"); scanf("%d", &tamanho); /* Processamento */ do { formapal(tamanho); printf("\nDigite o tamanho da proxima palavra \n"); scanf("%d", &tamanho); } while (tamanho!=0); /* Finaliza‡ao */ return 0; } 24 DSC/CCT/UFCG 5.8 Chamada de Funções por Valor e por Referência Uso na invocação de funções [email protected] [email protected] 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 25 DSC/CCT/UFCG 5.8 Chamada de Funções por Valor e por Referência [email protected] [email protected] Chamada por referência Passagem do(s) argumento(s) original(ais) Alterações do(s) argumento(s) na implicam alterações no(s) original(ais) Uso apenas com funções confiáveis precisem modificar a variável original função que Foco atual Chamada por valor 26 5.9 Geração de Números Aleatórios DSC/CCT/UFCG Função rand [email protected] [email protected] 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 27 5.9 Geração de Números Aleatórios DSC/CCT/UFCG Ajuste de Escala Obtenção de um número aleatório entre 1 e n [email protected] [email protected] 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 28 5.9 Geração de Números Aleatórios DSC/CCT/UFCG Função srand Inclusão de <stdlib.h> de uma “semente” (seed) inteira e deslocamento de sua seqüência “aleatória” para aquela locação srand( seed ); [email protected] [email protected] Definição srand( time( NULL ) ); time( // inclusão de <time.h> NULL ) Retorno do tempo no qual o program foi compilado (em segundos) “Aleatorização" da semente 29 [email protected] [email protected] DSC/CCT/UFCG 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 5.9 Geração de Números Aleatórios Programa para randomização no lançamento de um dado */ #include <stdlib.h> #include <stdio.h> int main() { int i; unsigned semente; Digite a semente: 67 6 1 4 6 printf( “Digite a semente: " ); scanf( "%u", &semente ); 1 6 1 6 srand(semente); for ( i = 1; i <= 10; i++ ) { printf( "%10d", 1 + ( rand() % 6 ) ); if ( i % 5 == 0 ) printf( "\n" ); Digite a semente: 867 } 2 4 6 1 return 0; 1 1 3 6 } 2 4 6 2 30 5.10 DSC/CCT/UFCG Exemplo: Jogo de Azar Simulador de Craps Regras [email protected] [email protected] 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 31 5.10 [email protected] [email protected] DSC/CCT/UFCG 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Exemplo: Jogo de Azar /* Simulador de Craps */ #include <stdio.h> #include <stdlib.h> #include <time.h> int rola_dados( void ); int main() { int placar, soma, ponto; srand( time( NULL ) ); soma = rola_dados(); /* primeiro lançamento dos dados */ switch ( soma ) { case 7: case 11: /* ganha na primeira rodada */ placar = 1; break; case 2: case 3: case 12: /* perde na primeira rodada */ placar = 2; break; default: /* armazena ponto */ placar = 0; ponto = soma; printf( “O total de pontos eh %d\n", ponto ); break; } while (placar == 0) { /* continua jogando */ soma = rola_dados(); 32 [email protected] [email protected] DSC/CCT/UFCG 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 5.10 if (soma == ponto) placar = 1; else if (soma == 7) placar = 2; Exemplo: Jogo de Azar /* vence fazendo ponto */ /* perde obtendo o valor 7 */ } if (placar == 1) printf( “O jogador venceu\n" ); else printf( " O jogador perdeu\n " ); return 0; O jogador lançou 14 + 36 = 410 O total de pontos eh 410 O jogador lançou 12 + 4 = 56 O jogador lançou 56 + 45 = 911 O jogador lançou 43 + 63 = 10 6 O jogador lançou 6 + 34 = 910 O jogador lançou venceu1 + 2 = 3 O jogador lançou 5 + 2 = 7 O jogador perdeu } int rola_dados( void ) { int dado1, dado2, soma; dado1 = 1 + ( rand() % 6 ); dado2 = 1 + ( rand() % 6 ); soma = dado1 + dado2; printf( “O jogador lançou %d + %d = %d vezes\n", dado1, dado2, soma ); return soma; } O O jogador jogador lançou lançou 66 ++ 65 == 12 11 O O jogador jogador perdeu venceu 33 DSC/CCT/UFCG 5.11 Classes de Armazenamento IDENTIFICADORES variáveis Possuem um nome, um tipo e um valor [email protected] [email protected] funções Possuem nome, tipo, valor e parâmetros IDENTIFICADORES também possuem Classes de armazenamento, tempo de validade, escopo e ligação. 34 DSC/CCT/UFCG 5.11 Classes de Armazenamento Especificadores de classes de armazenamento auto, register, extern e static Tempo (ou duração) de Armazenamento Período [email protected] [email protected] 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 35 5.11 Classes de Armazenamento DSC/CCT/UFCG [email protected] [email protected] 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 descartado objeto quando o bloco for 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; 36 5.11 Classes de Armazenamento DSC/CCT/UFCG [email protected] [email protected] 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 extern Default para variáveis globais e nomes de funções Conhecimento por qualquer função 37 DSC/CCT/UFCG 5.12 Regras de Escopo [email protected] [email protected] Escopo de Arquivo Identificador definido fora da função, conhecido por todas as funções Uso para variáveis globais, funções, protótipos de funções definições de Escopo de Função Referência possível apenas dentro do corpo de uma função Uso apenas para rótulos (start:, case:, etc.) 38 5.12 Regras de Escopo DSC/CCT/UFCG Escopo de Bloco [email protected] [email protected] 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 com nomes iguais em ambos os blocos Escopo de Protótipo de Função Uso para identificadores em listas de parâmetros 39 5.8 Variáveis globais DSC/CCT/UFCG Acesso a partir de qualquer função [email protected] [email protected] Declarar antes do main() Exemplo: #include ... void lerdados(); /* protótipo da função */ float nota; /* variável global */ main() { float melhor_nota; .. melhor_nota = nota; .. } void lerdados() /* função */ { ... scanf(("%s", ¬a); ... } 40 5.8 Variáveis globais DSC/CCT/UFCG #include <stdio.h> #include <string.h> void lerdados(); char nome[20]=""; float nota; [email protected] [email protected] int main() { char melhor_aluno[20]=""; int contador; float media, melhor_nota, soma; /* Inicialização */ soma = 0; contador = 0; lerdados(); /* chamada da função */ /* Processamento */ melhor_nota = nota; strcpy(melhor_aluno, nome); while (nota != -1) {soma = soma+nota; contador = contador + 1; lerdados(); /* chamada da função */ if (nota > melhor_nota) {melhor_nota = nota; strcpy(melhor_aluno, nome); } } /* Finalização */ if (contador != 0) {media = soma / contador; printf("\nA media da turma e: \n%.2f", media); printf("O melhor aluno eh: %s", melhor_aluno); printf(" com a nota %.2f", melhor_nota); } else printf("\nNenhum aluno digitado."); return 0; } void lerdados() { printf("Digite o nome do proximo aluno: "); scanf("%s", &nome); printf("\nDigite a nota deste aluno: "); scanf("%f", ¬a); return; } 41 [email protected] [email protected] DSC/CCT/UFCG 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 5.12 Regras de Escopo /* Exemplo de escopo */ #include <stdio.h> void a(void); /* protótipo da função a */ void b(void); /* protótipo da função b */ void c(void); /* protótipo da função c */ int x = 1; /* variável global */ int main() { int x = 5; /* variável local para main */ printf(“x local no escopo externo de main é %d\n", x ); { /* início de um novo escopo */ int x = 7; printf( “x local no escopo interno de main é %d\n", x ); } /* término do novo escopo */ printf( “x local no escopo externo de main é %d\n", x ); a(); /* a contém x local automática */ b(); /* b contém x local estática*/ c(); /* c usa x global */ a(); /* a reinicializa x local automática */ b(); /* x local estática mantém seu valor anterior */ c(); /* x global também mantém seu valor */ printf( “x local em main é %d\n", x ); return 0; } 42 [email protected] [email protected] DSC/CCT/UFCG 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 5.12 Regras de Escopo void a(void) { int x = 25; /* inicializada a cada vez em que a é chamada */ printf( "\nx local em a é %d depois de entrar em a\n", x ); ++x; printf( "x local em a é %d antes de sair de a\n", x ); } void b(void) { static int x = 50; /* inicializa somente na primeira vez em que b é chamada */ printf( "\nx local estática é %d ao entrar em b\n", x ); ++x; printf( " x local estática é %d ao sair de b\n", x ); } void c(void) { printf( "\n x global é %d ao entrar em c\n", x ); x *= 10; printf( " x global eh %d ao sair de c\n", x ); } 43 DSC/CCT/UFCG 5.12 Regras de Escopo x local no escopo externo de main é 5 x local no escopo interno de main é 7 x local no escopo externo de main é 5 x local em a é 25 depois de entrar em a x local em a é 26 antes de sair de a [email protected] [email protected] x local estática é 50 ao entrar em b x local estática é 51 ao sair de b x global é 1 ao entrar em c x global é 10 ao sair de c x local em a é 25 depois de entrar a x local em a é 26 antes de sair de a x local estática é 51 ao entrar em b x local estática é 52 ao sair de b x global é 10 ao entrar em c x global é 100 ao sair de c x local em main é 5 44 5.13 Recursividade DSC/CCT/UFCG Funções Recursivas Auto-chamadas Possibilidade de solução apenas de um caso [email protected] [email protected] básico Fragmentação de um problema em O que é possível fazer O que não é possível fazer Necessidade de tal parte do problema se assemelhe ao problema original (versão mais simples ou menor) 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 Função 45 5.13 Recursividade DSC/CCT/UFCG Funções Recursivas Caso básico eventualmente solucionado [email protected] [email protected] Extensão, processamento e solução do problema como um todo 46 5.13 Recursividade DSC/CCT/UFCG Exemplo [email protected] [email protected] Fatoriais 5! = 5 * 4 * 3 * 2 * 1 Importante observar que 5! = 5 * 4! 4! = 4 * 3! ... Possibilidade factoriais de computação recursiva de 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; 47 5.14 DSC/CCT/UFCG Exemplo de Recursividade: Fibonacci Uso Série de de Série de Fibonacci (0, 1, 1, 2, 3, 5, 8...) Cada número é a soma dos dois anteriores Possibilidade de solução recursiva [email protected] [email protected] 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); } 48 5.14 Exemplo de Recursividade: Fibonacci DSC/CCT/UFCG Série de chamadas fibonacci Uso Série de de recursivas à função [email protected] [email protected] f(3) return return f(1) return 1 f(2) + f(0) return 0 + f(1) return 1 49 5.14 [email protected] [email protected] DSC/CCT/UFCG 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 Exemplo de Recursividade: Fibonacci Uso Série de de /* Função recursiva da Série de Fibonacci */ #include <stdio.h> long fibonacci(long); int main() { long resultado, numero; printf(“Digite um inteiro: "); scanf( "%ld", &numero ); resultado = fibonacci(numero); printf("Fibonacci( %ld ) = %ld\n", numero, resultado); return 0; } /* Definição recursiva da função fibonacci */ long fibonacci(long n) { if (n == 0 || n == 1) return n; else return fibonacci(n - 1) + fibonacci(n - 2); } 50 5.14 DSC/CCT/UFCG Exemplo de Recursividade: Fibonacci Uso Série de de Exemplo de Saída Digite um inteiro: 2 Fibonacci(2) = 1 Digite um inteiro : 3 Fibonacci(3) = 2 [email protected] [email protected] 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 51 DSC/CCT/UFCG 5.15 Recursividade vs. Iteração Repetição Iteração Laço explícito Recursividade Chamadas repetidas à função [email protected] [email protected] Terminação Iteração Falha na condição do laço Recursividade Reconhecimento do caso básico Iteração/Recursividade Possibilidade de laços infinitos 52 DSC/CCT/UFCG 5.15 Recursividade vs. Iteração Ponto de Equilíbrio [email protected] [email protected] Ponderação entre desempenho (iteração) e qualidade da engenharia de software (recursividade ) 53 DSC/CCT/UFCG José Eustáquio Rangel de Queiroz Roberto Medeiros de Faria Ulrich Schiel UNIVERSIDADE FEDERAL DE CAMPINA GRANDE CENTRO DE CIÊNCIAS E TECNOLOGIA [email protected] DEPARTAMENTO DE SISTEMAS E COMPUTAÇÃO