FUNÇÕES
A maioria dos programas apresentados até agora usa somente a
função main. À medida que seus programas vão se tornando maiores
e mais complexos, você pode simplificar seu trabalho e melhorar a clareza
do programa dividindo o programa em partes menores chamadas funções.
Por exemplo, assuma que você esteja criando um programa de contabilidade.
Você poderia ter uma função que efetuasse as operações normais de um
contador, uma função diferente para as contas a pagar, uma terceira para
as contas a receber e uma quarta para gerar um balanço. Se você
colocasse todos os comandos do programa dentro de main,
seu programa ficaria muito grande, e seria difícil de entender. À medida
que o tamanho e a complexidade do programa aumentam, aumenta também a
possibilidade de erros. Se você dividir o programa em blocos menores e
mais facilmente gerenciáveis, poderá evitar os erros. Uma função é
uma coleção nomeada de comandos que efetuam uma tarefa específica. Por
exemplo, a função a seguir , usa printf para exibir uma mensagem:
#include <stdio.h>
void oi_pessoal (void)
{
printf (“Oi pessoal!\n”);
}
A palavra chave
void diz a C que a função não retorna um valor. Em muitos casos, suas funções
usarão return para retornar o resultado de um cálculo para a função chamadora.
Se a função não usa return para retornar um resultado, você deve preceder o nome da
função como void. O void que aparece nos parênteses diz a C que a função não usa
parâmetros. Um parâmetro é a informação que o programa passa para a função. Por exemplo, quando
seus programas chamam printf,as informações que você especifica dentro dos parênteses são
parâmetros. Quando uma função não usa parâmetros, você deve colocar a palavra void
dentro dos parênteses. Para usar uma função, você simplesmente especifica o nome da função seguido
por parênteses exatamente como usa printf.
Os programadores referenciam o uso de uma função como uma chamada da função. O programa a
seguir, usa a função oi_pessoal.
#include <stdio.h>
void oi_pessoal (void)
{
printf (“Oi pessoal!\n”);
}
void main(void)
{
oi_pessoal();
}
Ao executar esse programa, a função main
é executada primeiro. Como você pode ver, o único comando em main
é a chamada da função oi_pessoal.
Quando C encontra a chamada da função, imediatamente transfere a
execução do programa para a função, iniciando a execução do programa
para a função, iniciando a execução do programa com o primeiro comando
na função. Depois que o último comando na função termina, C transfere
a execução para o comando que segue imediatamente a chamada da função.
Para compreender melhor esse processo, mude a função main
como mostrado aqui:
void main (void)
{
printf(“Prestes a chamar a função\n”);
oi_pessoal();
printf(“Voltei da chamada da função\n”);
}
Quando você compilar e executar o programa, sua tela exibirá o seguinte:
Prestes a chamar a função
Oi pessoal!
Voltei da chamada da função
Usando
Variáveis Dentro das Funções
Á medida
que você cria funções úteis, verá que muitas
funções requerem que as variáveis gerem resultados valiosos. Para usar
uma variável dentro de uma função, você precisa primeiro declarar a
variável, exatamente como faz em main. Por
exemplo, o programa a seguir, chama a função tres_olas que usa a
variável contador em um laço for para exibir uma
mensagem três vezes:
#include <stdio.h>
void tres_olas (void)
{
int contador;
for (contador = 1; contador <= 3; contador++)
printf("Olá pessoal!\n");
}
void main(void)
{
tres_olas();
}
Quando você declara variáveis dentro de uma
função, os nomes usados para essas variáveis são exclusivos para a função.
Portanto se seu programa usa 10 funções diferentes e cada função usa uma
variável chamada contador, C considera a variável de cada função
como distinta. Se sua função requer muitas variáveis, você deverá
declarar as variáveis no início da função, exatamente como faria
dentro de main
Compreendendo main como uma função
Quando você cria um programa , usa o nome da função main
para determinar o primeiro comando que o programa executar. Na verdade, main
é uma função, de modo que, caso tenha perguntas sobre os tipos de
operações que você pode executar dentro de suas funções, a regra é
bem simples: tudo que você pode fazer em main você pode fazer dentro de
uma função. Exatamente como você pode declarar variáveis em main,
também pode declarar variáveis nas suas funções. Também é possível
usar construções tais como if, while e for em suas funções.
Finalmente, uma função pode chamar (usar) outra. Por exemplo, o programa
a seguir usa duas funções. Quando o programa inicia, main chama
a função tres_olas, que, por sua vez, chama a função oi_pessoal
três vezes para exibir mensagens na sua tela, como mostrado aqui:
#include <stdio.h>
void ola_pessoal (void)
{
printf("Ola pessoal!\n");
}
void tres_olas(void)
{
int contador;
for (contador = 1; contador <=3;contador++)
ola_pessoal();
}
void main (void)
{
tres_olas();
}
Introdução aos parâmetros
Um parâmetro é um valor passado a uma função. Á medida que você for usando funções regularmente, poderá passar parâmetros para uma função para melhorar a utilidade da
função. Por exemplo, considere a seguinte construção da função tres_olas,
que chama a função oi_pessoal três vezes:
void tres_olas (void)
{
int contador;
for(contador = 1; contador <=3; contador++)
oi_pessoal();
}
Uma função mais útil lhe permite especificar, com um parâmetro, o número
de vezes que você quer que o programa exiba a mensagem. Para
usar um parâmetro, sua função precisa especificar o nome e o tipo do
parâmetro, como mostrado aqui:
void ola_conta (int msg_conta)
Neste caso, função ola_conta suporta um parâmetro do
tipo int chamado msg_conta. Quando outra função, tal como main,
quiser usar ola_conta, a função precisa especificar o nome e o
tipo do parâmetro, como mostrado aqui:
ola_conta(2); //Exibir a mensagem duas vezes
ola_conta(100); //Exibir a mensagem cem vezes
ola_conta(1); //Exibir a mensagem uma vez
O programa a seguir, ilustra como você poderia usar uma função com um parâmetro:
#include <stdio.h>
void oi_pessoal (void)
{
printf("Ola pessoal!\n");
}
void ola_conta (int msg_conta)
{
int contador;
for (contador = 1; contador <=msg_conta;contador ++)
oi_pessoal();
}
void main (void)
{
printf("Exibe a msg duas vezes\n");
ola_conta(2);
printf("Exibe a msg cinco vezes\n");
ola_conta(5);
}
Como você pode ver, ver em main a chamada da função para ola_conta
inclui o valor que C atribuirá ao parâmetro msg_conta.
Nota:
Ao passar um parâmetro para uma função, o tipo de valor que você
passará para o parâmetro (tal como int, float, char
etc...) precisa corresponder ao tipo do parâmetro. Dependendo do seu
compilador, ele poderá detectar incompatibilidade nos tipos. Se seu
compilador não detectar as incompatibilidades nos tipos dos parâmetros,
poderão aparecer erros que serão muito difíceis de detectar e de
corrigir.
Usando parâmetros múltiplos
Como você aprendeu, um parâmetro é um valor que você passa para
a função. Em geral, você pode passar um número irrestrito de
parâmetros para uma função. No entanto, as pesquisas mostram que,
quando o número de parâmetro excede a sete, a função torna-se mais
difícil para compreender e usar corretamente, ficando, portanto, mais
susceptível a erros. Quando sua função usa mais de um parâmetro, você
precisa especificar o tipo e o nome de cada parâmetro e separar os
parâmetros por vírgulas, como mostrado aqui:
void uma_função(int idade, float sal, int num_cargo)
{
// Comandos da função
}
Quando seu programa quiser chamar a função, você precisará
especificar valores para cada parâmetro, como mostrado aqui:
uma_função(33,40000.00, 534);
C, por
sua vez, atribuirá os parâmetros, como mostrado na figura abaixo:
Compreendendo as declarações
de parâmetros em programas C mais antigos
Quando você cria uma função que usa parâmetros, normalmente
especifica o tipo e o nome de cada parâmetro, separados por vírgulas,
dentro do cabeçalho da função, como mostrado aqui:
void uma_função (int idade, float sal,int num_cargo)
{
// Comandos da Função
}
Se você trabalha com programas C mais antigos, verá que os
programadores declaravam os parâmetros assim:
void uma_função (idade, sal, num_cargo)
int idade;
float sal;
int num_cargo;
{
//Comandos da função
}
Se você encontrar essas declarações de parâmetros, deverá
compreender que, embora o formato da declaração seja ligeiramente
diferente, o propósito permanece o mesmo - especifica o tipo e o nome do
parâmetro. Caso você se sinta tentado a atualizar o formato da função,
certifique-se de que seu compilador aceita totalmente o novo formato.
Além disso, lembre-se que, quanto mais modificações você fizer no seu
programa, maiores serão suas chances de introduzir um erro. Como regra
geral, "Se está funcionando, não conserte!"
Retornando um valor de uma função
À medida que suas funções se tornarem mais complexas,
normalmente realizarão um cálculo e retornarão um resultado. Para fornecer um resultado ao chamador, uma função precisará
usar o comando return,que você implementará como mostrado aqui:
return (resultado);
O tipo de valor que a função retorna (int, float, char, etc...)
determina o tipo da função. Por exemplo, se uma função retorna um
valor do tipo int, você precisa preceder o nome da função com o
nome do tipo, como mostrado aqui:
int uma_função (int valor)
{
// Comandos da função
}
A função a seguir, i_cubo, retorna o cubo do valor inteiro
que o programa especifica como seu parâmetro, Por exemplo se o chamador
passa o valor 5 para a função, i_cubo retornará o valor 5*5*5,
ou 125:
int i_cubo (int valor)
{
return(valor*valor*valor);
}
Como você pode ver, a função usa o comando return para
retornar o resultado do cálculo ao chamador. O código dentro da
função de chamada pode atribuir o resultado da função chamada (também
conhecido como valor de retorno) a uma variável, ou código pode usar o
valor de retorno dentro de uma terceira função, tal como printf,
como mostrado aqui:
result = i_cubo(5);
printf(("O cubo de 5 é %d\n",i_cubo(5));
O programa a seguir usa a função i_cubo para determinar
vários valores diferentes ao cubo:
#include <stdio.h>
int i_cubo(int valor)
{
return(valor*valor*valor);
}
void main(void)
{
printf("O cubo de 3 é %d\n",i_cubo(3));
printf("O cubo de 5 é %d\n",i_cubo(5));
printf("O cubo de 7 é %d\n",i_cubo(7));
}
Os valores que você passa para uma função precisam corresponder
aos tipos de parâmetros contidos dentro da declaração dessa função.
Por exemplo, se você quiser determinar o cubo de um valor em ponto
flutuante, crie uma segunda função chamada f_cubo, como mostrado
aqui (observe que o valor de retorno também é do tipo float):
float f_cubo (float valor)
{
return (valor*valor*valor);
}
Compreendendo o comando return
Como você aprendeu, para uma função fornecer um resultado ao chamador, ela precisará usar o comando return
em uma função, C finaliza imediatamente a execução da função e
retorna o valor especificado para o chamador. O programa não executa
quaisquer outros comandos dentro da função após o comando return.
Em vez disso, ele continua a execução na função chamadora. À medida que você examina outros programas C, pode encontrar
funções que contêm múltiplos comandos return, cada um dos quais
retornando um valor para uma condição especifica. Por exemplo, considere
a função compara_valores, mostrada aqui:
int compara_valores (int primeiro, int segundo)
{
if (primeiro == segundo)
return(0);
else if (primeiro > segundo)
return(1);
else if (primeiro < segundo)
return(2);
}
Como regra, você deve tentar limitar suas funções a usar somente
um comando return. À medida que sua funções se tornarem maiores
e mais complexas, ter muitos comandos return normalmente tornará
as funções mais difíceis de compreender. Na maioria dos casos, você
pode reescrever sua função para que ela use somente um comando return,
como mostrado aqui:
int compara_vallores( int primeiro, int segundo)
}
int result;
if (primeiro == segundo)
result = 0;
else if(primeiro > segundo)
result = 1;
else if (primeiro < segundo)
result = 2;
return(result);
}
Neste caso, como a função é tão simples, você pode ter
dificuldade em compreender qual é a vantagem de usar um único comando return.
No entanto, á medida que suas funções se tornarem mais complexas, a
vantagem ficará mais clara. Você deve observar que, algumas vezes, usar
mais de um comando return produz código mais legível do que a
alternativa de um único return. Você deverá escrever o código
mais legível e facilmente modificável quando possível; se usar
múltiplos comando return atingir seu objetivo, então use tantos
comandos return quanto forem necessários.
Compreendendo os protótipos de função
Se você examinar atentamente o programa anterior, verá que as
chamadas das funções sempre aparecem no código do programa-fonte após
as funções que elas chamam. A maioria dos novos compiladores C precisa
conhecer os tipos de retorno e de parâmetro de uma função antes de o
programa chamar a função. Colocando as funções antes de seus
chamadores dentro do código de seu programa, você permitirá que o
compilador C conheça as informações que ele deverá ter antes de encontrar a chamada da
função. No entanto, à medida que seus programas ficam mais complexos,
pode tornar-se impossível para você colocar sempre as funções na ordem
correta. Portanto, C permite colocar protótipos de função no seu
programa, para descrever os tipos de parâmetros e de retorno de uma
função. Antes que a função seja usada pela primeira vez, o programa
pode incluir um protótipo similar ao seguinte:
#include <stdio.h>
int I_cubo(int);
float f_cubo(float);
void main(void)
{
printf("O cubo de 3 é %d\n, I_cubo(3));
printf("O cubo de 3.7 é %f\n, f_cubo(3.7));
}
int i_cubo(int valor)
{
return(valor*valor*valor);
}
float f_cubo(float valor)
{
return(valor*valor*valor);
}
Se você examinar os arquivos de cabeçalho .h, tais como stdio.h,
verá que eles contêm muitos protótipos de funções.
Compreendendo a biblioteca de execução
Ao ir escrevendo suas próprias funções, frequentemente você
verá que uma função que criou para um programa atende às necessidades
de um segundo programa. A capacidade de reutilizar as funções em mais de
um programa pode poupar um tempo considerável de execução e de teste.
Antes de gastar um tempo enorme desenvolvendo uma ampla variedade
de funções de propósito geral, não deixe de examinar as funções que
seu compilador fornece. Muitos compiladores referenciam essas funções
internas como biblioteca de execução. A maioria dos compiladores fornece
centenas de funções de biblioteca de execução com propósitos que vão
de abertura e trabalho com arquivos para acessar informações do disco ou
de diretório para determinar o tamanho de um string de caracteres. As
duas ou três ou três horas que você gastará para ler a documentação
da biblioteca de execução pouparão muitas horas de programação que,
de outra forma, você gastaria "reinventando a roda".
a matéria continua na aula 23
|