Você está na página 1de 7

FUNO

Funes so as estruturas que permitem ao usurio separar seus programas em blocos. Se no as


tivssemos, os programas teriam que ser curtos e de pequena complexidade. Para fazermos programas
grandes e complexos temos de constru-los bloco a bloco.
Sintaxe de uma funo:

tipo_de_retorno nome_da_funo (declarao_de_parmetros)


{
corpo_da_funo
}

O tipo-de-retorno o tipo de varivel que a funo vai retornar.


A declarao de parmetros uma lista com a seguinte forma geral:

tipo var1, tipo var2, ... , tipo varN

O tipo deve ser especificado para cada uma das N variveis de entrada. na declarao de parmetros
que informamos ao compilador quais sero as entradas da funo.
O corpo da funo onde as entradas so processadas, sadas so geradas ou outras coisas so feitas.

O Comando return
O comando return tem a seguinte forma geral:

return valor_de_retorno; ou return;

Digamos que uma funo est sendo executada. Quando se chega a uma declarao return a funo
encerrada imediatamente e, se o valor de retorno informado, a funo retorna este valor. importante
lembrar que o valor de retorno fornecido tem que ser compatvel com o tipo de retorno declarado para a
funo.
Uma funo pode ter mais de uma declarao return. Isto se torna claro quando pensamos que a funo
terminada quando o programa chega primeira declarao return. Abaixo esto dois exemplos de uso
do return:
Exemplo:
#include <stdio.h>
#include <conio.h>
int Quadrado (int a)
{
return (a*a);
}

//fim da funo

int main ()
{
int num;
printf ("Entre com um numero: ");
scanf ("%d",&num);
num=Quadrado(num);
printf ("\n\nO seu quadrado vale: %d\n",num);
return 0;
}

//fim do programa pincipal

Exemplo:
#include <stdio.h>
#include <conio.h>
int EPar (int a)
{
if (a%2)
return 0;
else
return 1;
}

/* Verifica se a e divisivel por dois */


/* Retorna 0 se nao for divisivel */
/* Retorna 1 se for divisivel */
// fim da funo

int main ()
{
int num;
printf ("Entre com numero: ");
scanf ("%d",&num);
if (EPar(num))
printf ("\n\nO numero e par.\n");
else
printf ("\n\nO numero e impar.\n");
getch();
return 0;
}

importante notar que, como as funes retornam valores, podemos aproveit-los para fazer
atribuies, ou mesmo para que estes valores participem de expresses. Mas no podemos fazer:
func(a,b)=x;

/* Errado! */

No segundo exemplo vemos o uso de mais de um return em uma funo.

Prottipos de Funes
At agora escrevemos as funes antes de escrevermos a funo main(). Isto , as funes esto
fisicamente antes da funo main(). Isto foi feito por uma razo. Imagine-se na pele do compilador. Se
voc fosse compilar a funo main(), onde so chamadas as funes, voc teria que saber com
antecedncia quais so os tipos de retorno e quais so os parmetros das funes para que voc pudesse
gerar o cdigo corretamente. Por isso as funes foram colocadas antes da funo main(): quando o
compilador chegasse funo main() ele j teria compilado as funes e j saberia seus formatos.
Muitas vezes teremos o nosso programa espalhado por vrios arquivos. Ou seja, estaremos chamando
funes em um arquivo que sero compiladas em outro arquivo.
A soluo so os prottipos de funes. Prottipos so declaraes de funes. Isto , voc declara uma
funo que ir usar. O compilador toma ento conhecimento do formato daquela funo antes de
compil-la.
Um prottipo tem o seguinte formato:
tipo_de_retorno nome_da_funo (declarao_de_parmetros);
onde o tipo-de-retorno, o nome-da-funo e a declarao-de-parmetros so os mesmos que voc
pretende usar quando realmente escrever a funo. Repare que os prottipos tm uma ntida semelhana

com as declaraes de variveis. Vamos implementar agora um dos exemplos anterior com algumas
alteraes e com prottipos:
#include <stdio.h>
float Quadrado (float a);
int main ()
{
float num;
printf ("Entre com um numero: ");
scanf ("%f",&num);
num= Quadrado (num);
printf ("\n\nO seu quadrado vale: %f\n",num);
getch();
return 0;
}
float Quadrado (float a)
{
return (a*a);
}

Observe que a funo Square() est colocada depois de main(), mas o seu prottipo est antes. Sem isto
este programa no funcionaria corretamente.
Usando prottipos voc pode construir funes que retornam quaisquer tipos de variveis. Os prottipos
no s ajudam o compilador. Eles ajudam a voc tambm: usando prottipos, o compilador evita erros,
no deixando que o programador use funes com os parmetros errados e com o tipo de retorno errado.

O Tipo void
Em ingls, void quer dizer vazio.. Ele nos permite fazer funes que no retornam nada e funes que
no tm parmetros. Podemos agora escrever o prottipo de uma funo que no retorna nada:
void nome_da_funo (declarao_de_parmetros);
Neste tipo de funo, no temos valor de retorno na declarao return. Alis, neste caso, o comando
return no necessrio na funo.
Podemos, tambm, fazer funes que no tm parmetros:
tipo_de_retorno nome_da_funo (void);
ou, ainda, que no tem parmetros e no retornam nada:
void nome_da_funo (void);
Um exemplo de funes que usam o tipo void:
#include <stdio.h>
#include <conio.h>
void Mensagem (void);
int main ()
{
Mensagem();
printf ("\tDiga de novo:\n");

Mensagem();
return 0;
}
void Mensagem (void)
{
printf ("Ola! Eu estou vivo.\n");
}

Se quisermos que a funo retorne algo, devemos usar a declarao return. Se no quisermos, basta
declarar a funo como tendo tipo-de-retorno void. Devemos lembrar agora que a funo main() uma
funo e como tal devemos trat-la. O compilador acha que a funo main() deve retornar um inteiro.
Isto pode ser interessante se quisermos que o sistema operacional receba um valor de retorno da funo
main(). Se o programa retornar zero, significa que ele terminou normalmente, e, se o programa retornar
um valor diferente de zero, significa que o programa teve um trmino anormal.

Variveis locais
Estas so aquelas que s tm validade dentro do bloco no qual so declaradas. Podemos declarar
variveis dentro de qualquer bloco. S para lembrar: um bloco comea quando abrimos uma chave e
termina quando fechamos a chave. Por exemplo, um comando for pode ter variveis locais e que no
sero conhecidas fora dali. A declarao de variveis locais a primeira coisa que devemos colocar num
bloco. A caracterstica que torna as variveis locais to importantes justamente a de serem exclusivas
do bloco. Podemos ter quantos blocos quisermos com uma varivel local chamada x, por exemplo, e elas
no apresentaro conflito entre elas.
Abaixo vemos um exemplo de variveis locais:
func1 (...)
{
int abc,x;
...
}
func (...)
{
int abc;
...
}
void main ()
{
int a,x,y;
for (...)
{
float a,b,c;
...
}
...
}

No programa acima temos trs funes. As variveis locais de cada uma delas no iro interferir com as
variveis locais de outras funes. Assim, a varivel abc de func1() no tem nada a ver (e pode ser
tratada independentemente) com a varivel abc de func2(). A varivel x de func1() tambm
completamente independente da varivel x de main(). As variveis a, b e c so locais ao bloco for. Isto
quer dizer que s so conhecidas dentro deste bloco for e so desconhecidas no resto da funo main().
Quando usarmos a varivel a dentro do bloco for estaremos usando a varivel a local ao for e no a
varivel a da funo main().

Parmetros formais

O segundo tipo de varivel que veremos so os parmetros formais. Estes so declarados como sendo as
entradas de uma funo. O parmetro formal uma varivel local da funo. Voc pode tambm alterar
o valor de um parmetro formal, pois esta alterao no ter efeito na varivel que foi passada funo.
Isto tem sentido, pois quando o C passa parmetros para uma funo, so passadas apenas cpias das
variveis. Isto , os parmetros formais existem independentemente das variveis que foram passadas
para a funo. Eles tomam apenas uma cpia dos valores passados para a funo.

Variveis globais
Variveis globais so declaradas fora de todas as funes do programa. Elas so conhecidas e podem ser
alteradas por todas as funes do programa. Quando uma funo tem uma varivel local com o mesmo
nome de uma varivel global a funo dar preferncia varivel local. Vamos ver um exemplo:
int z,k;
func1 (...)
{
int x,y;
...
}
func2 (...)
{
int x,y,z;
...
z=10;
...
}
main ()
{
int count;
...
}

No exemplo acima as variveis z e k so globais. Veja que func2() tem uma varivel local chamada z.
Quando temos ento, em func2(), o comando z=10 quem recebe o valor de 10 a varivel local, no
afetando o valor da varivel global z.
Evite ao mximo o uso de variveis globais. Elas ocupam memria o tempo todo (as locais s ocupam
memria enquanto esto sendo usadas) e tornam o programa mais difcil de ser entendido e menos geral.

Exerccio
Analise o seguinte programa e aponte o valor de cada varivel sempre que solicitado:
#include <stdio.h>
int num;
int func(int a, int b)
{
a = (a+b)/2; /* Qual e o valor de a apos a atribuicao? */
num -= a;
return a;
}
int main()
{
int first = 0, sec = 50;
num = 10;
num += func(first, sec); /* Qual e o valor de num, first e sec */
/* antes e depois da atribuicao?
*/

printf("\n\nConfira! num = %d\tfirst = %d\tsec = %d",num, first, sec);


return 0;
}

Passagem de parmetros por valor e passagem por referncia


Vimos que quando chamamos uma funo os parmetros formais da funo copiam os valores dos
parmetros que so passados para a funo. Isto quer dizer que no so alterados os valores que os
parmetros tm fora da funo. Este tipo de chamada de funo denominado chamada por valor. Isto
ocorre porque so passados para a funo apenas os valores dos parmetros e no os prprios
parmetros. Veja o exemplo abaixo:
#include <stdio.h>
float sqr (float num);
void main ()
{
float num,sq;
printf ("Entre com um numero: ");
scanf ("%f",&num);
sq=sqr(num);
printf ("\n\nO numero original e: %f\n",num);
printf ("O seu quadrado vale: %f\n",sq);
}
float sqr (float num)
{
num=num*num;
return num;
}

No exemplo acima o parmetro formal num da funo sqr() sofre alteraes dentro da funo, mas a
varivel num da funo main() permanece inalterada: uma chamada por valor.
Outro tipo de passagem de parmetros para uma funo ocorre quando alteraes nos parmetros
formais, dentro da funo, alteram os valores dos parmetros que foram passados para a funo. Este
tipo de chamada de funo tem o nome de chamada por referncia. Este nome vem do fato de que,
neste tipo de chamada, no se passa para a funo os valores das variveis, mas sim suas referncias (a
funo usa as referncias para alterar os valores das variveis fora da funo).
O C s faz chamadas por valor. Isto bom quando queremos usar os parmetros formais vontade
dentro da funo, sem termos que nos preocupar em estar alterando os valores dos parmetros que foram
passados para a funo. Mas isto tambm pode ser ruim s vezes, porque podemos querer mudar os
valores dos parmetros fora da funo tambm. H entretanto, no C, um recurso de programao que
podemos usar para simular uma chamada por referncia.
Quando queremos alterar as variveis que so passadas para uma funo, ns podemos declarar seus
parmetros formais como sendo ponteiros. Os ponteiros so a "referncia" que precisamos para poder
alterar a varivel fora da funo. O nico inconveniente que, quando usarmos a funo, teremos de
lembrar de colocar um & na frente das variveis que estivermos passando para a funo. Veja um
exemplo:
#include <stdio.h>
void Troca (int *a,int *b);
void main (void)
{
int num1,num2;
num1=100;
num2=200;
Troca (&num1,&num2);
printf ("\n\nEles agora valem %d
}

%d\n",num1,num2);

void Troca (int *a,int *b)


{
int temp;
temp=*a;
*a=*b;
*b=temp;
}

No muito difcil. O que est acontecendo que passamos para a funo Swap o endereo das
variveis num1 e num2. Estes endereos so copiados nos ponteiros a e b. Atravs do operador *
estamos acessando o contedo apontado pelos ponteiros e modificando-o. Mas, quem este contedo?
Nada mais que os valores armazenados em num1 e num2, que, portanto, esto sendo modificados!
Espere um momento... ser que ns j no vimos esta estria de chamar uma funo com as variveis
precedidas de &? J! assim que ns chamamos a funo scanf(). Mas porqu? Vamos pensar um
pouco. A funo scanf() usa chamada por referncia porque ela precisa alterar as variveis que
passamos para ela! No para isto mesmo que ela feita? Ela l variveis para ns e, portanto precisa
alterar seus valores. Por isto passamos para a funo o endereo da varivel a ser modificada!

Você também pode gostar