Obra: Programar em C/Funções
Matéria: Matemática
Nível: médio
que função uma função um pedaço de código que faz alguma tarefa específica pode ser chamado de qualquer parte do programa quantas vezes desejarmos podemos também dizer que funções agrupam operações em um só nome que pode ser chamado em qualquer parte do programa essas operações são então executadas todas as vezes que chamamos nome da função utilizamos funções para obter clareza do código separando pedaços de código da função main podemos entender mais facilmente que cada parte do código faz além disso para procurarmos por uma certa ação feita pelo programa basta buscar função correspondente isso torna muito mais fácil ato de procurar por erros reutilização muitas vezes queremos executar uma certa tarefa várias vezes ao longo do programa repetir todo código para essa operação muito trabalhoso torna mais difícil manutenção do código se acharmos um erro nesse código teremos que corrigi lo em todas as repetições do código chamar uma função diversas vezes contorna esses dois problemas independência uma função relativamente independente do código que chamou uma função pode modificar variáveis globais ou ponteiros mas limitando se aos dados fornecidos pela chamada de função ideia funções permitir você encapsular várias operações em um só escopo que pode ser invocado ou chamado através de um nome assim possível então chamar função de várias partes do seu programa simplesmente usando seu nome exemplo include int main void imprime_par imprime_par return no exemplo acima função imprime_par foi usada para executar pedaço de programa que imprime um par de números saída do programa acima será função imprime_par definida da seguinte forma void imprime_par int int printf programa completo em mostrado abaixo include declaração da função imprime_par essa função recebe dois inteiros como argumento os imprime da seguinte forma void imprime_par int int int main int argc char argv imprime_par chamando função imprime_par chamando novamente return implementação da função implementação da função pode conter várias linhas de código void imprime_par int int printf definição de funções em devem ser feitas antes do uso das mesmas por isso em nosso exemplo definimos função imprime_par antes de usá la dentro do main linha que define ou declara função também conhecida como assinatura da função normalmente as assinaturas das funções são definidas dentro de arquivos de cabeçalho definindo uma função uma função pode necessitar de alguns dados para que possa realizar alguma ação baseada neles esses dados são chamados parâmetros da função além disso função pode retornar um certo valor que chamado valor de retorno os parâmetros seus tipos devem ser especificados explicitamente assim como tipo do valor de retorno forma geral da definição de uma função tipo de retorno da função nome da função parâmetro parâmetro código para nome da função dos parâmetros valem as mesmas regras que foram dadas para os nomes de variáveis não podemos usar mesmo nome para funções diferentes em um programa t
adas para os nomes de variáveis não podemos usar mesmo nome para funções diferentes em um programa todas as funções devem ser definidas antes da função main ou deve ser feito protótipo da função que veremos mais adiante código deve estar dentro das chaves funciona como qualquer outro bloco valor de retorno freqüentemente uma função faz algum tipo de processamento ou cálculo precisa retornar resultado desse procedimento em isso se chama valor de retorno pode ser feito com instrução return para poder retornar um valor precisamos especificar seu tipo char int float double variações para efetivamente retornar um valor usamos instrução return seguida do valor de retorno que pode ou não vir entre parênteses um exemplo bem simples de função que retorna um valor inteiro int tres return poderia também ser return tipo de retorno além dos tipos normais de variáveis char int float double suas variações pode ser tipo especial void que na verdade significa que não há valor de retorno nota muitos livros dizem que função main tem tipo de retorno void que não está correto segundo padrão da linguagem função main deve ter retorno do tipo int compiladores como gcc darão mensagens de erro caso função main não seja definida corretamente parâmetros como já foi dito um parâmetro um valor que fornecido função quando ela chamada comum também chamar os parâmetros de argumentos embora argumento esteja associado ao valor de um parâmetro os parâmetros de uma função podem ser acessados da mesma maneira que variáveis locais eles na verdade funcionam exatamente como variáveis locais modificar um argumento não modifica valor original no contexto da chamada de função pois ao dar um argumento numa chamada de função ele copiado como uma variável local da função única maneira de modificar valor de um parâmetro usar ponteiros que serão introduzidos mais adiante para declarar presença de parâmetros usamos uma lista de parâmetros entre parênteses com os parâmetros separados por vírgulas cada declaração de parâmetro feita de maneira semelhante declaração de variáveis forma geral tipo nome por exemplo int funcao int int float funcao float preco int quantidade double funcao double angulo para especificar que função não usa nenhum parâmetro lista de parâmetros deve conter apenas palavra chave void no entanto ela freqüentemente omitida nesses casos portanto você poderia escrever qualquer uma destas duas linhas void funcao void void funcao note que os nomes dos parâmetros são usados apenas na própria função para distinguir os argumentos eles não têm nenhuma relação com as variáveis usadas para chamar função chamadas de funções para executar uma função fazemos uma chamada de função que uma instrução composta pelo nome da função seguido pela lista de argumentos entre parênteses nome_da_função arg arg arg os argumentos podem ser qualquer tipo de expressão podem ser variáveis valores constantes expressões matemáticas ou até mesmo outras chamadas de função lembre que você deve sempre dar mesmo núm
ressões matemáticas ou até mesmo outras chamadas de função lembre que você deve sempre dar mesmo número de argumentos que função pede além disso embora algumas conversões de tipo sejam feitas automaticamente pelo compilador você deve atender aos tipos de argumentos note que valor dos argumentos copiado para função de maneira que as variáveis originais ficam inalteradas mesmo que na função tentemos alterá las isso chamamos passagem de argumentos por valor ao contrário de por referência veremos como modificar as variáveis originais na seção ponteiros própria chamada de função também uma expressão cujo valor valor de retorno da função bastando colocá la no lado direito de um sinal de igual para guardar valor numa variável por exemplo se função quadrado retorna quadrado de um número inteiro podemos fazer assim para calcular quadrado de na variável int quadrado dois exemplos include int quadrado int return void saudacao void printf olá void despedida void printf fim do programa int main int numero resultado saudacao printf digite um número inteiro scanf numero resultado quadrado numero printf quadrado de numero resultado despedida return você veria na tela ao executar programa olá digite um número inteiro quadrado de fim do programa repare que ao chegar na chamada de uma função programa passa controle para essa função após seu término devolve controle para instrução seguinte na função original mais um exemplo com uma função de argumentos include multiplica numeros void mult float float float printf int main float mult return protótipo ou declaração de função quando um programa está sendo compilado uma chamada de função encontrada compilador precisa saber tipo de retorno os parâmetros da função para que ele possa manipulá los corretamente compilador só tem como saber isso se função já tiver sido definida portanto se tentarmos chamar uma função que está definida abaixo da linha onde estamos fazendo chamada ou mesmo em outro arquivo compilador dará uma mensagem de erro pois não conseguiu reconhecer função exemplo de erro de chamada de função int main int int soma erro função está definida abaixo desta linha void soma int int printf nesses casos podemos declarar uma função antes de defini la isso facilita trabalho de usar diversas funções você não precisará se importar com ordem em que elas aparecem nos arquivos declaração de função também chamada de protótipo de função nada mais que definição da função sem bloco de código como uma instrução ela deve ser seguida de um ponto vírgula portanto para declarar função int quadrado int return escreveríamos int quadrado int numa declaração também podemos omitir os nomes dos parâmetros já que estes são ignorados por quem chama função int quadrado int poderíamos por exemplo reorganizar início do programa exemplo dado um pouco acima que permitiria colocar as funções em qualquer ordem mesmo que houvesse entre elas include int quadrado int void saudacao void void despedida void seguem as funções do programa note que de
de int quadrado int void saudacao void void despedida void seguem as funções do programa note que definição da função não deve contradizer declaração da mesma função se isso ocorrer uma mensagem de erro será dada pelo compilador variáveis locais versus globais quando declaramos as variáveis nós podemos fazê lo dentro de uma função fora de todas as funções inclusive main as primeiras são as designadas como locais só têm validade dentro do bloco no qual são declaradas as últimas são as globais elas estão vigentes em qualquer uma das funções quando uma função tem uma variável local com mesmo nome de uma variável global função dará preferência variável local daqui conclui se bem que podemos ter variáveis com mesmo nome que contradiz que nós dissemos no capitulo das variáveis então reformulamos apenas na situação em que temos variáveis locais que colocada restrição de termos nomes diferentes caso contrário não conseguiríamos distinguir uma da outra largo alto são variáveis internas que fazem parte de minhafuncion espanhol para incultos as variáveis largo alto não estão definidas aqui abaixo isto quer dizer que elas nao tem nem um valor não podemos usar os valores definido dentro da minhafuncion pois não há nenhuma instrução que defina que valor usar lembre se computador não vai adivinhar qual valor usar deve se definir cada instrução void calcular não houve definição de valor entre parenteses long superficie largo alto error bip bip valor nao definido return superficie nesse exemplo abaixo poderemos usar valor das variáveis externas dentro de todas as funções exemplo include variaveis externas long largo long alto void f_soma soma uma variavel interna largo alto sao variaveis externas long soma largo alto printf largo alto soma long calcular long superficie largo alto return superficie int main void f_soma printf superficie ld calcular return curiosidade palavra reservada auto serve para dizer que uma variável local mas utilização de auto não mais necessária pois as variáveis declaradas dentro de um bloco já são consideradas locais passagem de parâmetros por valor por referência que nós temos feito quando chamamos uma função dita chamada por valor quer dizer quando chamamos uma função passamos parâmetros para função protótipo depois para função definição valor dos argumentos passados são copiados para os parâmetros da função estes existem das variáveis que foram passadas eles tomam apenas uma cópia do valor passado se esse valor for alterado valor dos argumentos passados não são alterados ou seja não são alterados os valores dos parâmetros fora da função este tipo de chamada de função denominado chamada ou passagem de parâmetros por valor dito de outra maneira passamos variável ela entra na definição da função como copia de entra como variável se variável for alterada no decorrer da função valor de não alterado include float quadrado float num protótipo da função quadrado int main float num res declaro variáveis num res printf entre com um numero scan
da função quadrado int main float num res declaro variáveis num res printf entre com um numero scanf num associo valor inserido variável num res quadrado num chamo função quadrado passo parâmetro num printf no numero original num printf seu quadrado vale res getchar return float quadrado float num descrição da função quadrado return num num retorna num ao quadrado quando função main executada ela chega meio vê uma chamada para função quadrado onde passado parâmetro num ela já estava espera pois viu protótipo ela então vai executar função que está depois da função do main que acontece que num vai ficar com quadrado do valor esse valor do main vai entrar novamente no main associado variável res depois temos impressão da variável num res ora que acontece que valor do num fica igual ao valor antes de entrar na função fazemos mesma coisa agora com variável vemos que agora função alterada resumindo valor variável quando entra numa outra função não alterado na passagem por valor quando valor do parâmetro alterado denominamos chamada ou passagem por referência não faz chamadas por referência mas podemos simular isto com outra arma do que são os ponteiros que serão melhor explicados mais adiante void como dissemos uma função retorna um valor pode receber parâmetros void utilizado da seguinte forma void função void codigo no exemplo acima palavra void define que não vai receber parâmetros não vai retornar qualquer valor ou melhor void uma explicitação do programador que aquela função não vai receber ou retornar nenhum valor valor da função ignorado mas função realmente retorna um valor por isso para que resultado não seja interpretado como um erro bom declarar void nota não se pode utilizar void na função principal main apesar de existirem exemplos com void em algumas bibliografias infelizmente alguns compiladores aceitam void main main especial tem de retornar um int uma execução bem sucedida do programa costuma retornar zero em caso de erro retorna um recursividade uma função pode chamar si própria uma função assim chamada função recursiva há várias operações matemáticas recursivas das quais exemplos bem conhecidos são seqüência de fibonacci fatorial daremos exemplo do cálculo do fatorial de um número definido como produto de todos os números naturais não nulos menores ou iguais ele por exemplo lê se cinco fatorial igual atenção convenção uma maneira de definir algoritmo de fatorial implementação correspondente seria esta include include int fat int if return fat else return int main int printf ndigite um valor para scanf printf no fatorial de fat return exemplo include include unsigned long fib unsigned int if return else return fib fib int main int printf ndigite um valor para scanf printf fib return vamos introduzir valor para este programa são feitas as seguintes chamadas recursivas observe estrutura upside down árvore de cabeça para baixo criada pelas chamadas recursivas fibonacci cada vez que sub rotina chama si mesmo ela deve armazenar estado atu
s chamadas recursivas fibonacci cada vez que sub rotina chama si mesmo ela deve armazenar estado atual da sub rotina linha atual que está sendo executada os valores de todas as variáveis etc em uma estrutura de dados chamada de pilha se você usar recursividade durante um longo período de tempo pilha vai ficar muito grande programa dará uma mensagem de aviso inline uma função inline em vez de ser chamada será movida para local de chamada no momento da compilação se fizermos um paralelismo com as diretivas de compilação como define ela vai substituir cada chamada da função pela própria função como fosse uma macro mas isto só tem vantagens para códigos pequenos para quem necessite muito da velocidade no processamento alguns compiladores já fazem isto automaticamente para tornar uma função inline basta preceder declaração da função com nome inline inline tipo_de_retorno nome_da_função argumentos código