Programação Orientada à Procedimentos II Programação Orientada à Procedimentos I Processamento Paralelo Lógica de Programação Introdução à Computação Informática Básica

 

 

Informática Básica
Introdução à Computação
Lógica de Programação
Programação Orientada à Procedimentos I
Programação Orientada à Procedimentos II

Processamento Paralelo

Aula 21

Aula 22

Aula 23



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