Subalgoritmos (Fun��es)
Defini��o | Porque usar as fun��es ? | Primeiro Exemplo | Formato Geral |
Par�metros | Localiza��o das Fun��es no Programa-fonte | Verifica��o dos tipos dos par�metros | Escopo de Vari�veis |
Fun��es e Procedimentos | Passagem de Par�metros por Refer�ncia | Passagem de Vetores por Par�metros |
Defini��o
Conjunto de comandos agrupados em um bloco, que recebe um nome e atrav�s deste pode ser evocado.
Porque usar fun��es ?
- Para permitir o reaproveitamento de c�digo j� constru�do(por voc� ou por outros programadores);
- Para evitar que um trecho de c�digo que seja repetido v�rias vezes dentro de um mesmo programa;
- Para permitir a altera��o de um trecho de c�digo de uma forma mais r�pida. Com o uso de uma fun��o � preciso alterar apenas dentro da fun��o que se deseja;
- Para que os blocos do programa n�o fiquem grandes demais e, por conseq��ncia, mais dif�ceis de entender;
- Para facilitar a leitura do programa-fonte de uma forma mais f�cil;
- Para separar o programa em partes(blocos) que possam ser logicamente compreendidos de forma isolada.
Primero Exemplo
Em primeiro lugar, imaginemos que voc� necessite v�rias vezes em seu programa imprimir a mensagem "Pressione a tecla ENTER" e esperar que o usu�rio tecle ENTER, caso o usu�rio tecle algo diferente o programa deve imitir um BEEP.
Voc� pode fazer um la�o de WHILE sempre que isto fosse necess�rio.
Uma alternativa � criar uma fun��o. Com o uso de fun��es, este processo de repeti��o fica simplificado. Observe o exemplo a seguir.
#include <stdio.h>void EsperaEnter() // Defini��o da fun��o
"EsperaEnter"
{
int tecla;
printf("Pressione ENTER\n");
do
{
tecla = getchar();
if (tecla !=13) // Se nao for ENTER
{
printf("Digite ENTER\n");
}
} while(tecla != 13); // 13 e' o codigo ASCII do ENTER
}void main()
{
EsperaEnter(); // Chamada da fun��o definida antes
// ...........
EsperaEnter(); // Chamada da fun��o definida antes
// ...........
EsperaEnter(); // Chamada da fun��o definida antes
}
Formato Geral de uma Fun��o em C
tipo_da_funcao NomeDaFuncao (Lista_de_Parametros)
{
// corpo da fun��o
}
A Lista_de_Parametros, tamb�m � chamada de Lista_de_Argumentos, � opcional.
Par�metros
A fim de tornar mais amplo o uso de uma fun��o, a linguagem C permite o uso de par�metros. Este par�metros possibilitam que se definida sobre quais dados a fun��o deve operar. A fun��o sound(freq), por exemplo, recebe como par�metro a freq��ncia do som a ser gerado, permitindo que se defina seu comportamento a partir deste valor.
Para definir os par�metros de uma fun��o o programador deve explicit�-los como se estive declarando uma vari�vel, entre os par�nteses do cabe�alho da fun��o. Caso precise declarar mais de um par�metro, basta separ�-los por v�rgulas. No exemplo a seguir temos a fun��o SOMA que possui dois par�metros, sendo o primeiro um float e o segundo um int.
void SOMA(float a, int b) // basta separar por v�rgulas
{
float result; // a declara��o de vari�veis � igual ao que
// se faz na fun��o main
result = a+b;
printf("A soma de %6.3f com %d � %6.3f\n, a,b,Result);
}
Os par�metros da fun��o na sua declara��o s�o chamados par�metros formais. Na chamada da fun��o os par�metros s�o chamados par�metros atuais/reais.
Os par�metros s�o passados para uma fun��o de acordo com a sua posi��o. Ou seja, o primeiro par�metro atual(da chamada) define o valor o primeiro par�metro formal (na defini��o da fun��o, o segundo par�metro atual define o valor do segundo par�metro formal e assim por diante. Os nomes dos par�metros na chamada n�o tem rela��o com os nomes dos par�metros na defini��o da fun��o.
No c�digo a seguir, por exemplo, a fun��o SOMA � chamada recebendo como par�metros as vari�veis "b" e "a", nesta ordem.
#include <stdio.h>
void SOMA(float a, int b) // basta separar os par�metros por v�rgulas
{
float result; // a declara��o de vari�veis � igual ao que
// se faz na fun��o main
result = a+b;
printf("A soma de %6.3f com %d � %6.3f\n, a,b,Result);
}int main()
{
int a;
float b;a = 10;
b = 12.3;
SOMA(b,a); // Chamada da fun��o SOMA(12.3,10);return 0;
}
O resultado do programa � a impress�o da seguinte mensagem: A soma de 12.300 com 10 � 22.300
Localiza��o das Fun��es no Fonte
A princ�pio podemos tomar com regra a seguinte afirmativa toda fun��o deve serdeclaradaantes de ser usada.
A declara��o de uma fun��o em linguagem C n�o � exatamente o que fizemos at� agora. O que estamos fazendo � a defini��o da fun��o antes de seu uso. Na defini��o da fun��o est� impl�cita a declara��o.
Alguns programadores preferem que o in�cio do programa seja a primeira parte de seu programa. Para isto a linguagem C permite que se declare uma fun��o, antes de defini-la. Esta declara��o � feita atrav�s do prot�tipo da fun��o. O prot�tipo da fun��o nada mais � do que o trecho de c�digo que especifica o nome e os par�metros da fun��o.
No exemplo a seguir a fun��o SOMA � prototipada antes de ser usada e assim p�de ser chamada antes de ser definida.
#include <stdio.h>
void SOMA(float a, int b); // Prot�tipo da fun��o SOMA
void main()
{
SOMA(16.7,15); // Chamada da fun��o SOMA antes de sua defini��o,
} // mas ap�s sua prototipa��oint SOMA(float a, int b) // Defini��o da fun��o SOMA
return 0;
{
float result; // a declara��o de vari�veis � igual ao que
// se faz na fun��o main
result = a+b;
printf("A soma de %f com %d � %6.3f\n, a,b,result);
}
Aten��o: existem compiladores mais simplificados ou antigos que n�o obrigam a declara��o da fun��oantes de seu uso !!! Muito cuidado com eles !! Veja no item a seguir.
Verifica��o dos Tipos dos Par�metros
A princ�pio, dados usados par�metros atuais(aqueles da chamada da fun��o) devem ser dos mesmos tipos dos par�metros formais. Se isto n�o ocorrer, mas a declara��o da fun��o vier antes de seu uso, os compiladores C modernos se encarregam de converter automaticamente os tipos como se estivesemos usando um CAST.
Entretanto, tenha muito cuidado se as tr�s condi��es a seguir se verificarem:
- se voc� estiver usando um compilador que n�o exige a declara��o antes da fun��o antes de seu uso;
- se voce usar uma fun��o antes de t�-la prototipado(declarado);
- se os par�metros formais e reais n�o forem exatamente do mesmo tipo
Se as tr�s condi��es se verificarem o resultado da execu��o da fun��o � �mprevis�vel !
No caso de voc� declarar corretamente a fun��o antes de us�-la, a convers�o de tipos � feita como no caso de vari�veis. No exemplo a seguir a fun��o SOMA � chamada com os par�metros reais dos tipos int e float, nesta ordem. Como na declara��o da fun��o o primeiro par�metro � float e o segundo � int, � feita uma convers�o de int para float no caso do primeiro par�metro e de float para int no caso do segundo par�metro.
#include <stdio.h>
void SOMA(float a, int b); // Prot�tipo da fun��o SOMA
void main()
{
float f;f = 20.7;
SOMA(16,f);
}
Neste exemplo o primeiro par�metro � convertido para 16.0 e o segundo para 20. O que ocorre, de fato, � que a chamada da fun��o � feita como se mesma fosse substitu�da por:
SOMA((float)16,(int)f);
Escopo de Vari�veis
Por escopo de uma vari�vel entende-se o bloco de c�digo onde esta vari�vel � v�lida. Com base nisto, temos as seguintes afirma��es:
- As vari�veis valem no bloco que s�o definidas;
- as vari�veis definidas dentro de uma fun��o recebem o nome de vari�veis locais;
- os par�metros formais de uma fun��o valem tamb�m somente dentro da fun��o;
- uma vari�vel definida dentro de uma fun��o n�o � acess�vel em outras fun��es, MESMO ESTAS VARI�VEIS TENHAM NOME ID�NTICOS.
No trecho de c�digo a seguir tem-se um exemplo com fun��es e vari�veis com nomes iguais.
#include <stdio.h>
void FUNC1()
{
int B; B = -100;
printf("Valor de B dentro da fun��o FUNC1: %d\n", B);
}
void FUNC2()
{
int B; B = -200;
printf("Valor de B dentro da fun��o FUNC2: %d\n", B);
} void main()
{
int B;
B = 10;
printf("Valor de B: %d\n", B);
B = 20;
FUNC1();
printf("Valor de B: %d\n", B);
B = 30;
FUNC2();
printf("Valor de B: %d\n", B);
getch();
}SA�DA
Valor de B: 10
Valor de B dentro da fun��o FUNC1: -100
Valor de B: 20
Valor de B dentro da fun��o FUNC2: -200
Valor de B: 30
Sugere-se, antes da leitura das pr�ximas se��es, a consulta � p�gina sobre ponteiros.
Passagem de Par�metros por refer�ncia
A passagem de par�metros apresentada a at� aqui � chamada de passagem por valor. Nesta modalidade, a chamada da fun��o passa o valor do par�metro para a fun��o. Desta forma, altera��es do par�metro dentro da fun��o n�o afetar�o a vari�vel usada na chamada da fun��o.No exemplo a seguir a vari�vel f, passada por par�metro para a fun��o Zera n�o ser� alterado dentro da
fun��o.
#include <stdio.h>
void Zera(float a){
a = 0;
}
void main()
{
float f;
f = 20.7;
Zera(f);
printf("%d", f); // o valor impresso ser� 20.7 pois o par�metro da fun��o foi passado por
valor.
}
Para passar o endere�o de uma vari�vel para uma fun��o, deve-se tomar as seguintes provid�ncias:
- na chamada da fun��o deve-se usar o operador & antes do nome da vari�vel;
- no cabe�alho da fun��o,
- dentro da fun��o, deve-se usar o operado de derrefer�ncia * para alterar o conte�do da vari�vel.
O exemplo a seguir apresenta uma nova vers�o da fun��o Zera, desta feita com o uso de um par�metro passado por refer�ncia.
#include <stdio.h>
void Zera(float *a) // Define que o par�metro � uma refer�ncia � outra vari�vel{
*a = 0; // utiliza o operador de derrefer�ncia para alterar o conte�do da vari�vel
}
void main()
{
float f;
f = 20.7;
Zera(&f); // Passa o endere�o da vari�vel f para a fun��o
printf("%d", f); // o valor impresso ser� 0.0 pois o par�metro da fun��o foi passado por
refer�ncia.
}
Passagem de Vetores por Par�metros
A passagem de vetores por par�metro � sempre por refer�ncia. Isto significa que n�o se deve, na chamada da fun��o, passar o endere�o do vetor. Isto ocorre pois, por conven��o, o nome do vetor j� representa o endere�o inicial deste vetor namem�ria.No cabe�alho da fun��o que recebe um vetor, h� duas formas de definir o par�metro que � um vetor. Na primeira declara-se o vetor como se faz normalmente na linguagem. O exemplo a seguir mostra o uso desta abordagem.void ZeraVet(float V[10], int qtd)
{
int i;
for(i=0;i<qtd;i++)
V[i] = 0.0;
}
void main()
{
int i;
float Vet[10];
ZeraVet(Vet,10); // Passa o nome do vetor como
par�metro
printf("%d ", Vet[i]); // todos os elementos ter�o valor 0.0
} Na segunda abordagem, pode-se declarar o par�metro como um ponteiro para o tipo de dado que forma o vetor. No caso do exemplo a seguir, como o vetro foi declarado com um vetor de float, o par�metro da fun��o deve ser float *v.
No c�digo da fun��o, o acesso aos dados do vetor � feito da mesma maneira que � feito quando se declara o vetor explicitamente.void ZeraVet2(float *V, int qtd)
{
int i;
for(i=0;i<qtd;i++)
V[i] = 0;
}
void main()
{
int i;
float Vet[10];
ZeraVet(Vet,10); // Passa o nome do vetor como par�metro
for(i=0;i<10;i++)
printf("%d ", Vet[i]); // todos os elementos ter�o valor 0.0
}