Universidade Federal de Uberlândia Faculdade de Computação Linguagem C: funções Prof. Renato Pimentel 1 Subprogramas Subprograma: programa que auxilia o programa principal na realização de uma determinada subtarefa. Também conhecido como sub-rotina, procedimento, função, método ou módulo. Os subprogramas são chamados dentro do programa principal, como outros comandos. Após seu término, a execução continua a partir do ponto onde foram chamados. A chamada de um subprograma portanto gera um desvio provisório no fluxo de execução. 2 Prof. Renato Pimentel 1
Linguagem C: funções Em C, é mais utilizado o termo função. Exemplos clássicos: printf( ): função que escreve algo na tela; scanf( ): função que lê informação via teclado. Facilitam a estruturação e reutilização do código: Estruturação: programas complexos construídos bloco a bloco. Reutilização: uso de funções evita a cópia desnecessária de trechos de código que realizam a mesma tarefa, diminuindo assim o tamanho do programa e a ocorrência de erros. 3 Funções: criando Forma geral de uma função: tipo_retornado nome_funcao (tipo1 parametro1,..., tipon parametron) { } declarações e comandos; return valor ou expressão; 4 Prof. Renato Pimentel 2
Funções: criando Forma geral de uma função: tipo_retornado nome_funcao (tipo1 parametro1,..., tipon parametron) { } declarações e comandos; return valor ou expressão; Tipo de informação que a função retorna (devolve) para o lugar de onde foi chamada. 5 Funções: criando Forma geral de uma função: tipo_retornado nome_funcao (tipo1 parametro1,..., tipon parametron) { declarações e comandos; return valor ou expressão; } Declaração de parâmetros: lista de variáveis, juntamente com seus tipos. Função sem parâmetros: ( ) ou (void) 6 Prof. Renato Pimentel 3
Funções: criando Forma geral de uma função: tipo_retornado nome_funcao (tipo1 parametro1,..., tipon parametron) { declarações e comandos; return valor ou expressão; } Corpo da função: processa os parâmetros, realiza outras ações e, quando necessário, gera saída de dados 7 Exemplo: Funções: criando tipo_retornado nome_funcao (tipo1 parametro1,..., tipon parametron) { declarações e comandos; return valor ou expressão; } Corpo da função: processa os parâmetros, realiza outras ações e, quando necessário, gera saída de dados 8 Prof. Renato Pimentel 4
Corpo de uma função Ainda sobre o corpo da função: Todo programa possui ao menos 1 função: a função main( ) função principal ou corpo do programa Em geral, definimos main( ) com tipo int e retornando 0. Função main( ) comunicação com o usuário (operações de entrada e saída) Corpo da função consiste de: Sequência de declarações: variáveis, constantes, arrays, etc. Sequência de comandos: condicionais, de repetição, chamada de outras funções etc. 9 Corpo de uma função Ainda sobre o corpo da função: Convém-se evitar fazer operações de leitura e escrita dentro de uma função; O ideal é que operações de entrada e saída de dados ex.: funções scanf( ) e printf( ) sejam realizadas na função principal, main( ). 10 Prof. Renato Pimentel 5
Exemplo Exemplo de função: Somando dois valores inteiros 11 Exemplo de função: Exemplo Somando dois valores inteiros Obs.: Errado escrever nos parâmetros int x, y (como em declaração de mais de uma variável do mesmo tipo). 12 Prof. Renato Pimentel 6
Usando o return Exemplo de função: Uma função pode possuir mais de um comando return. 13 Exemplo de função: Usando o return Uma função pode possuir mais de um comando return. O valor de retorno deve ser compatível com o tipo de retorno declarado para a função. 14 Prof. Renato Pimentel 7
Chamada de função Usando uma função chamada Funções devem ser definidas antes de serem utilizadas (chamadas) Portanto, antes da função main( ). Veja exemplo a seguir. 15 Chamada de função Exemplo de uso: quadrado de um valor inteiro 16 Prof. Renato Pimentel 8
Chamada de função Exemplo de uso: quadrado de um valor inteiro int a = n1 n2 = (retorno) Chamada da função sqr 17 Protótipo de uma função Usando uma função chamada Funções devem ser definidas antes de serem utilizadas (chamadas); Todavia, é possível usar um protótipo da função, onde passamos somente o seu tipo de retorno, seu nome e seus parâmetros, antes da função main( ); Dessa forma, podemos definir cada função depois da função main( ). Veja exemplo a seguir. 18 Prof. Renato Pimentel 9
Protótipo de uma função Protótipo da função sqr( ). 19 Variáveis: escopo Escopo de uma variável Define onde e quando a variável pode ser usada. Escopo global: Fora de qualquer definição de função; Tempo de vida é o tempo de execução do programa; Escopo local: Bloco ou função (trecho entre { } ) 20 Prof. Renato Pimentel 10
Variáveis: escopo Escopo local: Bloco: visível apenas no interior de um bloco de comandos if (teste == 1) { } int i; i = i+1; Função: declarada na lista de parâmetros da função ou definida dentro da função int minha_fun (int x, int y) { } int i, j; 21 Variáveis: escopo Escopo global Escopo local Escopo local dentro de outro escopo local 22 Prof. Renato Pimentel 11
Variáveis: escopo Escopo dos parâmetros formais de uma função: Os dados de entrada da função (variáveis de sua lista de parâmetros) são também variáveis locais da mesma. 23 Variáveis: escopo Variáveis globais são declaradas fora de todas as funções do programa; Desta forma, tornam-se conhecidas e podem ser alteradas por qualquer função; Porém, se uma função possui uma variável local com o mesmo nome de uma variável global, função dará preferência à local. 24 Prof. Renato Pimentel 12
Variáveis: escopo 25 Passagem de parâmetros na chamada de uma função Passagem de parâmetros: Por valor: Neste caso, uma cópia do valor é feita na declaração do parâmetro, e passada à função Mesmo que este valor seja alterado dentro da função, nada acontece com o valor do dado fora da função. 26 Prof. Renato Pimentel 13
Passagem de parâmetros na chamada de uma função Passagem de parâmetros: Por valor 27 Passagem de parâmetros na chamada de uma função Passagem de parâmetros: Por valor 28 Prof. Renato Pimentel 14
Passagem de parâmetros na chamada de uma função Passagem de parâmetros: Por referência: Quando se deseja alterar o valor da variável, devemos fazer a passagem de parâmetros por referência. Neste tipo de chamada, não se passa para a função o valor da variável, mas seu endereço na memória! Para passar um parâmetro por referência, coloca-se um asterisco (*) na frente do nome do parâmetro na declaração da função. Ao se chamar a função, é necessário agora utilizar o operador de endereço & como feito para scanf( ). 29 Passagem de parâmetros na chamada de uma função Passagem de parâmetros: Por referência 30 Prof. Renato Pimentel 15
Passagem de parâmetros na chamada de uma função Passagem de parâmetros: Por referência 31 Funções e arrays Arrays são passados sempre por referência! Passagem por valor evita cópia desnecessária de grandes quantidades de dados em memória RAM; Evita-se assim queda de desempenho na execução do programa. Quando um array é passado por parâmetro, o que a função recebe é o endereço de seu primeiro elemento; Pode ser necessário enviar à função um parâmetro inteiro, informando à mesma o tamanho do array. 32 Prof. Renato Pimentel 16
Funções e arrays Pode ser necessário enviar à função um parâmetro inteiro, informando à mesma o tamanho do array. Podemos declarar a função de diferentes maneiras, todas equivalentes: void imprime (int *m, int n); void imprime (int m[], int n); void imprime (int m[5], int n); 33 Funções e arrays Exemplo: 34 Prof. Renato Pimentel 17
Funções e arrays multidimensionais Para arrays multidimensionais, é necessário especificar o tamanho de todas as dimensões, exceto a primeira. Ex.: void imprime (int m[][5], int n); Na passagem de um array para uma função, o compilador precisar saber o tamanho de cada elemento, não o número de elementos. Um array 2D pode ser visto como um array de arrays. int m[4][5]: array de 4 elementos onde cada elemento é um array de 5 posições inteiras. 35 Funções e arrays multidimensionais Exemplo 36 Prof. Renato Pimentel 18
Funções e arrays multidimensionais As notações abaixo funcionam para arrays com mais de uma dimensão. Mas o array é tratado como se tivesse apenas uma dimensão dentro da função: void imprime (int*m, int n); void imprime (int m[], int n); 37 Funções e arrays multidimensionais Exemplo 38 Prof. Renato Pimentel 19
Recursão Em linguagem C, uma função pode chamar outra. Ex.: A função main( ) pode chamar qualquer função, seja ela de uma biblioteca padrão da linguagem C (como a função printf( )) ou definida pelo programador. Veja também o exemplo visto no slide 27, onde é printf( ) é chamado dentro da função soma( ). Em particular, uma função pode chamar a si própria Função recursiva. 39 Recursão Um exemplo clássico de função recursiva: Fatorial de um valor inteiro. Propriedades: 1. n! = n (n-1) (n-2) (n-3) 1 = n(n-1)! Ou seja, o fatorial de um número qualquer corresponde ao produto deste número pelo fatorial de seu antecessor. 2. 0! = 1 Podemos criar uma função que recebe um inteiro n e retorne seu fatorial, como mostrado a seguir. 40 Prof. Renato Pimentel 20
Recursão int fatorial(int n) { if (n == 0) return 1; else { int i, f = 1; for (i = 2; i <= n; i++) f = f*i; return f; } } 41 Recursão No exemplo anterior, não aproveitamos a primeira propriedade. Para aproveitá-la, reescrevemos a função, tornando-a recursiva. int fatorial(int n) { } if (n == 0) else { } return 1; return n*fatorial(n-1); 42 Prof. Renato Pimentel 21
Recursão Recursividade: ideia de dividir e conquistar: Divide-se problema maior em conjunto de problemas menores; Resolvem-se os menores de forma independente; Soluções dos mesmos, combinadas, geram solução do problema maior Caso do fatorial: O fatorial de 4 é dado em função do fatorial de 3; O fatorial de 3 é dado em função do fatorial de 2; O fatorial de 0 é dado como sendo 1 (caso-base). 43 Recursão O caminho de ida da recursão (chamadas) para no caso base; a partir do mesmo, voltamos, retornando os valores para a função que chama. 44 Prof. Renato Pimentel 22
Recursão Saber identificar o caminho de ida da recursão, o caso base e o caminho de volta da recursão torna sua implementação mais simples. Alguns cuidados a serem tomados: Critério de parada: determina quando a função deverá parar de chamar a si mesma; O parâmetro da chamada recursiva deve ser sempre modificado, de forma que a recursão chegue a um término. 45 Recursão int fatorial(int n) { if (n == 0) // criterio de parada else { return 1; return n*fatorial(n-1); /* parametro do fatorial sempre muda */ } } 46 Prof. Renato Pimentel 23
Recursão O que acontece na chamada da função fatorial com um valor como, por exemplo, 4? int x = fatorial(4); 47 Recursão Caminho de volta da recursão, após caso base. int x = fatorial(4); 48 Prof. Renato Pimentel 24
Recursão Outro exemplo: sequência de Fibonacci F(0) = 0 F(1) = 1 F(n) = F(n-1)+F(n-2), n >= 2 Implementação da função: int fibo(int n) { if (n == 0 n == 1) return n; else return fibo(n-1)+fibo(n-2); } 49 Recursão Outro exemplo: sequência de Fibonacci Baixa eficiência 50 Prof. Renato Pimentel 25
Recursão Outro exemplo: sequência de Fibonacci Agora fibo(5): 51 Exercícios 1. Escreva uma função que receba dois valores e retorne qual o maior deles. 2. Escreva uma função que receba uma temperatura dada em graus Fahrenheit e retorne o valor da mesma em graus Celsius, sendo que C = 5*(F-32)/9. 3. Escreva uma função que receba e troque os valores de duas variáveis numéricas do mesmo tipo. 52 Prof. Renato Pimentel 26
Exercícios 4. Crie uma função que receba uma matriz quadrada 2x2 e retorne seu determinante. A seguir, crie um programa que leia as entradas da matriz do usuário e que calcule o mesmo através da função e o mostre na tela. 5. Crie uma função recursiva que receba um valor inteiro N e calcule o somatório dos números de 1 a N. 53 Referências BACKES, A. Linguagem C: completa e descomplicada. Rio de Janeiro: Elsevier, 2013. PAIVA, J. G. S. Notas de aula de algoritmos e programação de computadores. TRAVENÇOLO, B. A. N. Notas de aula de Introdução à Programação e Computadores. 54 Prof. Renato Pimentel 27