Funções
Durante o desenvolvimento de nossos programas, fazemos chamadas a funções predefinidas em bibliotecas inclusas em nossos programas. Por exemplo, utilizamos as funções matemáticas: abs, sin, cos, pow, sqrt, etc. Utilizamos as funções de entrada e saida no dispositivo padrão: printf, scanf, getchar, etc. Inclusive, além das funções disponíveis para uso em nossos programas, em C, existe a possibilidade de criarmos nossas proprias funções para chamarmos no programa principal ou em qualquer bloco de código. Abaixo a sintaxe de uma função criada pelo programador:
tipo nome( tipo1 p1, tipo2 p2, ..., tipoN pN ) { BLOCO DE CÓDIGO }
Abaixo um exemplo de função:
int soma( int a, int b ) {
return a + b;
}
A função acima é simples de compreender. Trata-se de uma função que recebe dois parâmetros inteiros e retorna a soma, também como valor inteiro. Atenção: a função é declarada fora da função main. Abaixo o exemplo completo:
#include <stdio.h>
int soma( int a, int b ) {
return a + b;
}
int main() {
int a, b, result;
printf( "Informe o primeiro numero: " );
scanf( "%d", &a );
printf( "Informe o segundo numero: " );
scanf( "%d", &b );
result = soma( a, b );
printf( "\nA soma eh: %d", result );
return 0;
}
No programa acima, a função soma recebe parâmetros atribuidos as variáveis a e b e, essas variáveis só existem dentro da função e não têm nada a ver com as variáveis a, e b do programa principal. Por exemplo, poderia ser n1 e n2 no programa principal, ao invés de a e b. Isso porque cada variável tem seu escopo. As variáveis declaradas dentro de uma função só existem dentro da função.
Abaixo, um exemplo de função que altera o valor de duas variáveis, assim como, a função scanf.
#include <stdio.h>
void inverte_valores( int* a, int* b ) {
int aux;
aux = *a;
*a = *b;
*b = aux;
}
int main() {
int a = 1;
int b = 2;
printf( "A=%d, B=%d", a, b );
inverte_valores( &a, &b );
printf( "\nA=%d, B=%d", a, b );
return 0;
}
No programa acima, é declarada uma função que inverte os valores de duas variáveis alterando seu conteúdo. Repare que os tipos na função antecedem um *, o que significa que, a função recebe como parâmetro, não um valor de variável, e, sim, uma referência (Endereço de memória). Para utilizar o endereço de memória de uma variável, ela deve ser precedida de um &, assim como um dos parâmetros da função scanf que recebe como parâmetro uma referência a uma variável que tem seu valor alterado para o valor lido. Para acessar/alterar o conteúdo referenciado por uma variável de referência, utilize o * antes do nome da variável de referência.
Abaixo uma função para ler um número inteiro:
#include <stdio.h>
void ler_inteiro( int* n ) {
printf( "Informe o numero: " );
scanf("%d",n);
}
void imprime_inteiro( int n ) {
printf( "\nFoi informado o numero: %d", n );
}
int main() {
int num;
ler_inteiro( &num );
imprime_inteiro( num );
return 0;
}
Repare no exemplo acima que a função ler_inteiro espera como parâmetro uma referência a uma variável inteira. Repare também que na função scanf não é necessário utilizar o operador & antes do nome da variável. A passagem de parâmetros por referência é feita no programa principal com a chamada da função ler_inteiro.
Abaixo, uma calculadora de áreas com a definição de funções:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float area_retangulo( float base, float altura ) {
return base * altura;
}
float area_triangulo( float base, float altura ) {
return ( base * altura ) / 2;
}
float area_circulo( float raio ) {
return M_PI * pow( raio, 2 );
}
void menu() {
system( "cls" );
printf( "Calculadora de Areas" );
printf( "\n(1) Retangulo" );
printf( "\n(2) Triangulo" );
printf( "\n(3) Circulo" );
printf( "\n(0/Esq) Sair" );
printf( "\n\n" );
}
int main() {
char op = '\0';
float base, altura, raio, result;
do {
menu();
printf( "Informe a opcao: " );
fflush( stdin );
fflush( stdout );
op = getchar();
printf( "\n" );
switch( op ) {
case '1':
printf( "Informe a base do retangulo: " );
scanf( "%f", &base );
printf( "Informe a altura do retangulo: " );
scanf( "%f", &altura );
result = area_retangulo( base, altura );
printf( "A area do retangulo eh: %.2f", result );
fflush( stdin );
fflush( stdout );
getchar();
break;
case '2':
printf( "Informe a base do triangulo: " );
scanf( "%f", &base );
printf( "Informe a altura do triangulo: " );
scanf( "%f", &altura );
result = area_triangulo( base, altura );
printf( "A area do triangulo eh: %.2f", result );
fflush( stdin );
fflush( stdout );
getchar();
break;
case '3':
printf( "Informe o raio do circulo: " );
scanf( "%f", &raio );
result = area_circulo( raio );
printf( "A area do circulo eh: %.2f", result );
fflush( stdin );
fflush( stdout );
getchar();
break;
}
} while( op != '0' && (int)op != 27 );
printf( "\nSaindo..." );
}
O programa acima é uma calculadora de áreas em que é mostrado um menu e o usuário pode escolher qual tipo de área deseja calcular. Atenção a função: system o parâmetro para esta função pode ser qualquer comando do MS-DOS, nesse caso, foi utilizado o comando cls que serve para limpar a tela. Outro detalhe importante é comando getchar que serve para dar uma parada na tela. Isto é, após imprimir um resultado, o programa espera que o usuário digite uma tecla (pode ser enter) para, então a tela ser limpa e o menu ser impresso novamente. Atenção a função menu que retorna um valor do tipo void, ou seja, o tipo de retorno é declarado como void quando a função não retorna nada. A função printf é um exemplo de função que não retorna nada. Na condição do do/while é verificado se o usuário digitou o número 0 ou ESQ como opção escolhida do menu. Repare que a variável op é convertida para int e comparada com o código inteiro da tecla ESQ conforme a tabela ASCII.
Recomendação: Pesquise sobre a tabela ASCII!
Abaixo uma função que verifica se um número é primo ou não:
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int eh_primo( int n ) {
int i;
int eh = TRUE;
for( i = 2; eh == TRUE && i <= n/2; i++ )
if ( n % i == 0 )
eh = FALSE;
return eh;
}
int main() {
int num;
int primo;
printf( "Informe um numero: " );
scanf( "%d", &num );
primo = eh_primo( num );
if ( primo == TRUE )
printf( "\nO numero %d eh primo!", num );
else printf( "\nO numero %d nao eh primo!", num );
return 0;
}
Na função que verifica se um número é primo definida acima, a variável eh declarada como int é do tipo condição. Seus valores podem ser VERDADE(TRUE) ou FALSO(FALSE). O tipo de retorno da função também é do tipo condição, ou seja, a função retorna um, caso o número passado como parâmetro seja primo ou retorna zero, caso o parâmetro não seja primo.
Veja o exemplo de função abaixo:
void imprime_mensagem( int n ) {
if ( n > 10 ) {
printf( "O numero eh maior que 10" );
return;
}
printf( "O numero eh menor ou igual a 10" );
}
O que faz o programa acima? É simples! Se o número (n) for maior que 10, a devida mensagem é impressa e, logo após, é chamado o return sem tipo de retorno, o que finaliza a execução da função sem a execução do ultimo comando. Caso o número seja menor ou igual a 10, a primeira mensagem não é mostrada e o return não é executado e, então, a ultima instrução printf é executada e a mensagem impressa na tela. A função acima equivale a função abaixo:
void imprime_mensagem( int n ) {
if ( n > 10 ) {
printf( "O numero eh maior que 10" );
} else {
printf( "O numero eh menor ou igual a 10" );
}
}
Veja abaixo outro exemplo:
int absoluto( n ) {
if ( n < 0 )
return -n;
return n;
}
Na função acima, é retornado o valor absoluto de um número, isto é, se for negativo é retornado sem o sinal de menos. Ou seja, se n < 0 (O número é negativo) então é retornado o número convertido para positivo com um (-n) e a ultima intrução return não é executada. Caso o número seja positivo (n >= 0), então o return do if não é executado e, então, é executado o segundo return.
Sobrecarga de funções
A linguagem C permite a sobrecarga de funções. Por isso, é possível declarar mais de uma função com mesmo nome, desde que as funções de mesmo nome tenham conjunto de parâmetros diferentes. Por exemplo, o seguinte exemplo está correto:
#include <stdio.h>
int adiciona( int a, int b ) {
return a + b;
}
int adiciona( int n ) {
return adiciona( n, 1 );
}
int main() {
printf( "%d %d", adiciona( 2 ), adiciona( 3, 4 ) ); // imprime 3 e 7
return 0;
}
Exercício
1) Crie uma "calculadora aritmética" com as funções: soma, subtração, multiplicação e divisão. Se baseie no exemplo "calculadora de áreas" mostrado anteriormente.