Você está na página 1de 10

14/03/2017 Programar em C/Funes - Wikilivros

Programar em C/Funes
Origem: Wikilivros, livros abertos por um mundo aberto.
< Programar em C

Este mdulo precisa ser revisado por algum que conhea o assunto ( discuta).

ndice
1 O que funo
2 Definindo uma funo
2.1 Valor de retorno
2.2 Parmetros
2.3 Chamadas de funes
3 Dois exemplos
4 Prottipo ou Declarao de funo
5 Variveis locais versus globais
6 Passagem de parmetros por valor e por referncia
7 void
8 Recursividade
9 inline

O que funo
Uma funo um pedao de cdigo que faz alguma tarefa especfica e pode ser chamado de qualquer parte do
programa quantas vezes desejarmos.

Podemos tambm dizer que funes agrupam operaes em um s nome que pode ser chamado em qualquer
parte do programa. Essas operaes so ento executadas todas as vezes que chamamos o nome da funo.

Utilizamos funes para obter:

Clareza do cdigo: separando pedaos de cdigo da funo main(), podemos entender mais facilmente o
que cada parte do cdigo faz. Alm disso, para procurarmos por uma certa ao feita pelo programa,
basta buscar a funo correspondente. Isso torna muito mais fcil o ato de procurar por erros.

Reutilizao: muitas vezes queremos executar uma certa tarefa vrias vezes ao longo do programa.
Repetir todo o cdigo para essa operao muito trabalhoso, e torna mais difcil a manuteno do
cdigo: se acharmos um erro nesse cdigo, teremos que corrigi-lo em todas as repeties do cdigo.
Chamar uma funo diversas vezes contorna esses dois problemas.

Independncia: uma funo relativamente independente do cdigo que a chamou. Uma funo pode
modificar variveis globais ou ponteiros, mas limitando-se aos dados fornecidos pela chamada de funo.

A ideia funes permitir voc encapsular vrias operaes em um s escopo que pode ser invocado ou
chamado atravs de um nome. Assim possvel ento chamar a funo de vrias partes do seu programa
simplesmente usando o seu nome.

Exemplo:

https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 1/10
14/03/2017 Programar em C/Funes - Wikilivros

#include <stdio.h>
int main(void) {
imprime_par (3,4);
imprime_par (-2,8);
return 0;
}

No exemplo acima, a funo imprime_par foi usada para executar o pedao de programa que imprime um par
de nmeros. A sada do programa acima ser:

{3,4}
{-2,8}

A funo imprime_par definida da seguinte forma:

void imprime_par (int a, int b)


{
printf ("{ %d, %d } \n",a,b);
}

O programa completo em C mostrado abaixo:

#include <stdio.h>

/**
* Declarao da funo imprime_par
* Essa funo recebe dois inteiros como argumento e os imprime
* da seguinte forma {a,b}
*/
void imprime_par (int a, int b);

int main(int argc, char **argv)


{
imprime_par (3,4); //chamando a funo
imprime_par (-2,8); //chamando novamente
return 0;
}

//Implementao da funo
//A implementao da funo pode conter vrias linhas de cdigo
void imprime_par (int a, int b)
{
printf ("{ %d, %d } \n",a,b);
}

A definio de funes em C devem ser feitas antes do uso das mesmas. Por isso em nosso exemplo definimos
a funo imprime_par antes de us-la dentro do main.

A linha que define ou declara a funo tambm conhecida como assinatura da funo. Normalmente as
assinaturas das funes so definidas dentro de arquivos de cabealho .h

Definindo uma funo


Uma funo pode necessitar de alguns dados para que possa realizar alguma ao baseada neles. Esses dados
so chamados parmetros da funo. Alm disso, a funo pode retornar um certo valor, que chamado valor
de retorno. Os parmetros (e seus tipos) devem ser especificados explicitamente, assim como o tipo do valor
de retorno.

A forma geral da definio de uma funo :

https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 2/10
14/03/2017 Programar em C/Funes - Wikilivros

[tipo de retorno da funo] [nome da funo] (1 parmetro, 2 parmetro, )


{
//cdigo
}

Para o nome da funo e dos parmetros valem as mesmas regras que foram dadas para os nomes de
variveis. No podemos usar o mesmo nome para funes diferentes em um programa.

Todas as funes devem ser definidas antes da funo main, ou deve ser feito o prottipo da funo, que
veremos mais adiante.

O cdigo deve estar obrigatoriamente dentro das chaves e funciona como qualquer outro bloco.

Valor de retorno

Freqentemente, uma funo faz algum tipo de processamento ou clculo e precisa retornar o resultado desse
procedimento. Em C, isso se chama valor de retorno e pode ser feito com a instruo return. Para poder
retornar um valor, precisamos especificar seu tipo (char, int, float, double e variaes). Para efetivamente
retornar um valor, usamos a instruo return seguida do valor de retorno, que pode ou no vir entre parnteses.
Um exemplo bem simples de funo que retorna um valor inteiro:

int tres()
{
return 3; // poderia tambm ser return (3);
}

O tipo de retorno, alm dos tipos normais de variveis (char, int, float, double e suas variaes), pode ser o tipo
especial void, que na verdade significa que no h valor de retorno.

Nota Muitos livros dizem que a funo main tem tipo de retorno void, o que no est correto.
Segundo o padro da linguagem C, a funo main deve ter retorno do tipo int. Compiladores como o
gcc daro mensagens de erro caso a funo main() no seja definida corretamente.

Parmetros

Como j foi dito, um parmetro um valor que fornecido funo quando ela chamada. comum tambm
chamar os parmetros de argumentos, embora argumento esteja associado ao valor de um parmetro.

Os parmetros de uma funo podem ser acessados da mesma maneira que variveis locais. Eles na verdade
funcionam exatamente como variveis locais, e modificar um argumento no modifica o valor original no
contexto da chamada de funo, pois, ao dar um argumento numa chamada de funo, ele copiado como uma
varivel local da funo. A nica maneira de modificar o valor de um parmetro usar ponteiros, que sero
introduzidos mais adiante.

Para declarar a presena de parmetros, usamos uma lista de parmetros entre parnteses, com os parmetros
separados por vrgulas. Cada declarao de parmetro feita de maneira semelhante declarao de variveis:
a forma geral tipo nome. Por exemplo:

int funcao (int a, int b)


float funcao (float preco, int quantidade )
double funcao (double angulo )

https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 3/10
14/03/2017 Programar em C/Funes - Wikilivros

Para especificar que a funo no usa nenhum parmetro, a lista de parmetros deve conter apenas a palavra-
chave void. No entanto, ela freqentemente omitida nesses casos. Portanto, voc poderia escrever qualquer
uma destas duas linhas:

void funcao (void)


void funcao ()

Note que os nomes dos parmetros so usados apenas na prpria funo (para distinguir os argumentos); eles
no tm nenhuma relao com as variveis usadas para chamar a funo.

Chamadas de funes

Para executar uma funo, fazemos uma chamada de funo, que uma instruo composta pelo nome da
funo, seguido pela lista de argumentos entre parnteses:

nome_da_fun o (arg1, arg2, arg3, ...);

Os argumentos podem ser qualquer tipo de expresso: podem ser variveis, valores constantes, expresses
matemticas ou at mesmo outras chamadas de funo.

Lembre que voc deve sempre dar o mesmo nmero de argumentos que a funo pede. Alm disso, embora
algumas converses de tipo sejam feitas automaticamente pelo compilador, voc deve atender aos tipos de
argumentos.

Note que o valor dos argumentos copiado para a funo, de maneira que as variveis originais ficam
inalteradas mesmo que na funo tentemos alter-las. A isso chamamos passagem de argumentos por
valor (ao contrrio de por referncia). Veremos como modificar as variveis originais na seo
Ponteiros.

A prpria chamada de funo tambm uma expresso cujo valor o valor de retorno da funo, bastando
coloc-la no lado direito de um sinal de igual para guardar o valor numa varivel. Por exemplo, se a funo
"quadrado" retorna o quadrado de um nmero inteiro, podemos fazer assim para calcular o quadrado de 11 na
varivel x:

int x = quadrado (11);

Dois exemplos

#include <stdio.h>

int quadrado (int x)


{
return (x * x);
}

void saudacao (void)


{
printf ("Ol!\n");
}

void despedida (void)


{
printf ("Fim do programa. \n");
}

https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 4/10
14/03/2017 Programar em C/Funes - Wikilivros

int main ()
{
int numero , resultado ;
saudacao ();

printf ("Digite um nmero inteiro: " );


scanf ("%d", &numero );
resultado = quadrado (numero );
printf ("O quadrado de %d %d. \n", numero , resultado );

despedida ();
return 0;
}

Voc veria na tela, ao executar o programa:

Ol!
Digite um nmero inteiro: 42
O quadrado de 42 1764.
Fim do programa.

Repare que, ao chegar na chamada de uma funo, o programa passa o controle para essa funo e, aps seu
trmino, devolve o controle para a instruo seguinte na funo original.

Mais um exemplo, com uma funo de 3 argumentos:

#include <stdio.h>

/* Multiplica 3 numeros */
void mult (float a, float b, float c)
{
printf ("%f",a*b*c);
}

int main ()
{
float x, y;
x = 23.5;
y = 12.9;
mult (x, y, 3.87);
return 0;
}

Prottipo ou Declarao de funo


Quando um programa C est sendo compilado e uma chamada de funo encontrada, o compilador precisa
saber o tipo de retorno e os parmetros da funo, para que ele possa manipul-los corretamente. O compilador
s tem como saber isso se a funo j tiver sido definida. Portanto, se tentarmos chamar uma funo que est
definida abaixo da linha onde estamos fazendo a chamada, ou mesmo em outro arquivo, o compilador dar uma
mensagem de erro, pois no conseguiu reconhecer a funo.

//Exemplo de erro de chamada de funo


int main()
{
int a = 1;
int b = 2;
soma(a,b); // erro: a funo est definida abaixo desta linha!
}
void soma(int a, int b)
{
printf ("%d", a+b);
}

https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 5/10
14/03/2017 Programar em C/Funes - Wikilivros

Nesses casos, podemos declarar uma funo antes de defini-la. Isso facilita o trabalho de usar diversas
funes: voc no precisar se importar com a ordem em que elas aparecem nos arquivos.

A declarao de funo (tambm chamada de prottipo de funo) nada mais que a definio da funo sem o
bloco de cdigo. Como uma instruo, ela deve ser seguida de um ponto-e-vrgula. Portanto, para declarar a
funo:

int quadrado (int x)


{
return (x * x);
}

escreveramos:

int quadrado (int x);

Numa declarao, tambm podemos omitir os nomes dos parmetros, j que estes so ignorados por quem
chama a funo:

int quadrado (int);

Poderamos, por exemplo, reorganizar o incio do programa-exemplo dado um pouco acima, o que permitiria
colocar as funes em qualquer ordem mesmo que houvesse interdependncia entre elas:

#include <stdio.h>

int quadrado (int x);


void saudacao (void);
void despedida (void);

// seguem as funes do programa

Note que a definio da funo no deve contradizer a declarao da mesma funo. Se isso ocorrer, uma
mensagem de erro ser dada pelo compilador.

Variveis locais versus globais


Quando declaramos as variveis, ns podemos faz-lo

Dentro de uma funo


Fora de todas as funes inclusive a main().

As primeiras so as designadas como locais: s tm validade dentro do bloco no qual so declaradas. As


ltimas so as globais, elas esto vigentes em qualquer uma das funes.

Quando uma funo tem uma varivel local com o mesmo nome de uma varivel global a funo dar
preferncia varivel local. Daqui conclui-se e bem que, podemos ter variveis com o mesmo nome, o que
contradiz o que ns dissemos no capitulo das variveis.

Ento reformulamos:

Apenas na situao em que temos 2 variveis locais que colocada a restrio de termos nomes
diferentes caso contrrio no conseguiramos distinguir uma da outra.

"largo" e "alto" so variveis internas fazem parte de "minhaFuncion()".

https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 6/10
14/03/2017 Programar em C/Funes - Wikilivros

/*espanhol para incultos :)*/ <== Coment rios da funo


void minhaFuncion ()
{
double largo = 5;
double alto = 6;
}

As variveis largo e alto no esto definidas aqui abaixo, isto quer dizer que elas nao tem nem um valor.

E no podemos usar os valores definido dentro da "minhaFuncion", pois no h nenhuma instruo que defina
que valor usar. Lembre-se: O computador no vai adivinhar qual valor usar. Deve-se definir cada instruo.

void calcular () /*No houve definio de valor entre parenteses*/


{
long superficie = largo * alto; /*Error bip bip valor nao definido*/
return (superficie );
}

Nesse exemplo abaixo, poderemos usar o valor das variveis externas dentro de todas as funes. Exemplo:

#include <stdio.h>
/* Variaveis externas */
long largo = 10;
long alto = 20;

void F_soma ()
{
/*soma uma variavel interna
e largo e alto sao variaveis externas */
long soma = largo + alto ;
printf ("largo + alto = %i \n", soma);
}

long calcular ()
{
long superficie = largo * alto;
return superficie ;
}

int main(void)
{
F_somma ();
printf ("Superficie : %ld \n", calcular () );
return 0 ;

Curiosidade A palavra reservada "auto" serve para dizer que uma varivel local, mas a utilizao de auto
no mais necessria pois as variveis declaradas dentro de um bloco j so consideradas locais.

Passagem de parmetros por valor e por referncia


O que ns temos feito quando chamamos uma funo a dita chamada por valor. Quer dizer, quando
chamamos uma funo e passamos parmetros para a funo prottipo e depois para a funo definio, o valor
dos argumentos passados so copiados para os parmetros da funo. Estes existem independentemente das
variveis que foram passadas. Eles tomam apenas uma cpia do valor passado, e se esse valor for alterado o
valor dos argumentos passados no so alterados. Ou seja, no so alterados os valores dos parmetros fora da
funo. Este tipo de chamada de funo denominado chamada (ou passagem de parmetros) por valor.

Dito de outra maneira. Passamos a varivel a, ela entra na definio da funo como copia de a e entra
como varivel b. Se a varivel b for alterada no decorrer da funo, o valor de a no alterado.

https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 7/10
14/03/2017 Programar em C/Funes - Wikilivros

#include <stdio.h>
float quadrado (float num); //prottipo da funo quadrado()
int main ()
{
float num, res; //declaro 2 variveis: num , res
printf ("Entre com um numero: " );
scanf("%f", &num); //associo o valor inserido varivel num
res = quadrado (num); //chamo a funo quadrado e passo o parmetro num
printf ("\n\nO numero original e: %f \n", num);
printf ("e seu quadrado vale: %f \n", res);
getchar ();
return 0;
}
float quadrado (float num) //descrio da funo quadrado
{
return num * num; //retorna num ao quadrado
}

Quando a funo main() executada, ela chega a meio e v uma chamada para a funo quadrado() e onde
passado o parmetro "num". Ela j estava a espera, pois "viu" o prottipo. Ela ento vai executar a funo que
est depois da funo do main(). E o que acontece que o "num", vai ficar com o dobro do valor. Esse valor do
main() vai entrar novamente no main(). E associado varivel "res". Depois temos a impresso da varivel
"num" e "res". Ora o que acontece que o valor do "num" fica igual ao valor antes de entrar na funo.
Fazemos a mesma coisa agora com a varivel "a" e "b", e vemos que agora a funo a alterada. Resumindo, o
valor varivel quando entra numa outra funo no alterado (na passagem por valor).

Quando o valor do parmetro alterado denominamos chamada (ou passagem) por referncia. O C no faz
chamadas por referncia. Mas podemos simular isto com outra arma do C que so os ponteiros, que sero
melhor explicados mais adiante.

void
Como dissemos, uma funo retorna um valor. E pode receber parmetros. O void utilizado da seguinte
forma:

void funo(void)
{
//codigo
}

No exemplo acima, a palavra void define que:

no vai receber parmetros; e


no vai retornar qualquer valor.

Ou melhor, void uma explicitao do programador que aquela funo no vai receber ou retornar nenhum
valor.

O valor da funo ignorado, mas a funo realmente retorna um valor, por isso para que o resultado no seja
interpretado como um erro e bom declarar void.

Nota

No se pode utilizar void na funo principal main, apesar de existirem exemplos com void em algumas
bibliografias. Infelizmente, alguns compiladores aceitam void main(). O main() especial e tem de
retornar um int. Uma execuo bem sucedida do programa costuma retornar 0 (zero) e, em caso de erro,
retorna 1 (um).

Recursividade
https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 8/10
14/03/2017 Programar em C/Funes - Wikilivros

Uma funo pode chamar a si prpria. Uma funo assim chamada funo recursiva. H vrias operaes
matemticas recursivas, das quais exemplos bem conhecidos so a seqncia de Fibonacci e o fatorial.

Daremos o exemplo do clculo do fatorial de um nmero, definido como o produto de todos os nmeros
naturais (no nulos) menores ou iguais a ele por exemplo, 5! (l-se "cinco fatorial") igual a
. Ateno conveno .

Uma maneira de definir o algoritmo de fatorial :

E a implementao correspondente seria esta:

#include <stdio.h>
#include <stdlib.h>

int fat(int n)
{
if (n)
return n*fat(n-1);
else return 1;
}

int main()
{
int n;
printf ("\n\nDigite um valor para n: " );
scanf("%d", &n);
printf ("\nO fatorial de %d e' %d" , n, fat(n));
return 0;
}

Exemplo 2 :

#include <stdio.h>
#include <stdlib.h>

unsigned long fib(unsigned int n){


if (n == 0 || n == 1)
return n;
else
return fib(n - 1) + fib(n - 2);
}

int main(){
int n;
printf ("\n\nDigite um valor para n: " );
scanf("%d", &n);
printf ("\n F(%d) = %d \n ",n, fib(n));
return 0;

Vamos introduzir o valor 5 para este programa.

So feitas as seguintes chamadas recursivas. Observe a estrutura upside-down (rvore de cabea para baixo)
criada pelas chamadas recursivas.

Fibonacci(5)
/ \
/ \
/ \
/ \
/ \
F(4) + F(3)
/ \ / \
https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 9/10
14/03/2017 Programar em C/Funes - Wikilivros
/ \ / \
/ \ / \
/ \ / \
/ \ / \
F(3) + F(2) F(2) + F(1)
/\ /\ | \ \
/ \ / \ | \ \
/ \ / \ | \ \
/ \ / \ | \ \
F(2) + F(1) F(1) + F(0) F(1) + F(0) 1
/\ | | | | |
/ \ | | | | |
/ \ | | | | |
/ \ | | | | |
F(1) + F(0) 1 1 0 1 0
| |
| |
| |
| |
1 0

Cada vez que a sub-rotina chama a si mesmo, ela deve armazenar o estado atual da sub-rotina (linha atual que
est sendo executada, os valores de todas as variveis, etc) em uma estrutura de dados chamada de "pilha".

Se voc usar a recursividade durante um longo perodo de tempo, a pilha vai ficar muito grande e o programa
dar uma mensagem de aviso.

inline
Uma funo inline, em vez de ser chamada, ser movida para o local de chamada no momento da compilao.

Se fizermos um paralelismo com as diretivas de compilao, como #define, ela vai substituir cada chamada da
funo pela prpria funo, como fosse uma macro.

Mas isto s tem vantagens para cdigos pequenos e para quem necessite muito da velocidade no
processamento. Alguns compiladores j fazem isto automaticamente.

Para tornar uma funo inline basta preceder a declarao da funo com o nome inline.

inline [tipo_de_retorno] [nome_da_funo] (argumentos)


{
//cdigo
}

Obtido em "https://pt.wikibooks.org/w/index.php?title=Programar_em_C/Funes&oldid=421989"

Categoria: !Mdulos precisando de reviso

Curta o Wikilivros no Facebook [ignorar]

Esta pgina foi modificada pela ltima vez (s) 04h12min de 29 de maio de 2016.
Este texto disponibilizado nos termos da licena Creative Commons Atribuio-Compartilhamento pela
mesma Licena 3.0 Unported; pode estar sujeito a condies adicionais. Consulte as Condies de Uso
para mais detalhes.

https://pt.wikibooks.org/wiki/Programar_em_C/Fun%C3%A7%C3%B5es 10/10

Você também pode gostar