PRÁTICA - MODULARIZAÇÃO

 

 

INTRODUÇÃO
 

Uma das características mais importantes da linguagem C são as funções, pois são nelas que ocorrem todas as atividades de um programa. Cada função equivale a um bloco de instruções, o qual pertence exclusivamente à mesma, não podendo ser acessado por nenhuma outra, exceto por meio de uma chamada à esta função.

 

Dividindo o programa em várias funções, torna-se mais fácil a detecção de erros e organização do código. É importante observar que na linguagem C não existe distinção entre funções (possui um único retorno) e procedimentos (não possui retorno algum).

 
 
DECLARAÇÃO E ESTRUTURA DE UMA FUNÇÃO EM C
 
    Em geral, a declaração de uma função se faz da seguinte maneira:
 

<tipo de dado> <identificador> (lista de parâmetros)

 

Tipo de dado: especifica o tipo de valor que o comando return devolve á função, consistindo do seu único valor de retorno. Quando este campo não foi informado, o compilador interpreta como seu tipo de dado padrão int (inteiro).

 

Identificador: corresponde ao nome dado a função, respeitando todas as regras de dar nomes a objetos (variáveis e constantes) na programação computacional.

 

Lista de parâmetros: compreende valores que serão enviados pela chamada da função que necessita enviar alguns dados para dentro dela, de forma que ela possa resolver corretamente o que lhe é solicitado.

 
    (<tipo de dados><identificador>,.....);
 

É similar a uma "lista de variáveis" separadas por vírgula e entre os parênteses da função, com seus respectivos tipos de dados totalmente compatíveis com os definidos em sua declaração (protótipo da função). Uma função pode ter vários parâmetros ou nenhum, mas sempre deve possuir seus parênteses: ( - abrir e ) - fechar.

 

Exemplos - observe alguns protótipos a seguir:

 

float media (float nota1,float nota2); //função
                                       //float com 2 parâmetros float
int soma (int valor1, int valor2);  //função int com 
                                   //2 parâmetros int
char mostra ( );  //função char sem nenhum parâmetro
potencia (int exp, float base, char resp);
    /* função POTENCIA sem definição explícita do seu tipo assume o tipo de dado padrão da linguagem C (int) com três parâmetros, sendo o primeiro int, o segundo float e o terceiro char, independentemente do seu tipo de dado de retorno */
 

A função deve ser declarada no início do programa a ser elaborado por meio do seu protótipo. Após a criação da função principal (função main), o corpo da função desejada, e já declarada pelo seu protótipo, deve ser definido, consistindo ele na cópia de sua declaração (protótipo), sem o ponto e vírgula (;) no final. Em seguida, similar a função principal, o corpo da nova função começa a ser definido, sempre entre chaves: { - abrir e } - fechar.

 

Exemplo - observe o corpo da função MEDIA que teve seu protótipo (declaração) realizado no exemplo anterior:

 
float media (float nota1, float nota2)
{
  //Declarações
        float resultado;  //criação de uma nova variável, sendo ela local
  //Instruções
        resultado = (nota1 + nota2) / 2;
        return (resultado);
}
 

Este exemplo mostra uma função que calcula a média entre duas notas e retorna o resultado deste cálculo. Observe qual seria o algoritmo desta função e veja a similaridade da criação de ambos.

 
funcao real media (real nota1, real nota2) //corpo da função
     real resultado;  //criação da variável local resultado
     resultado = (nota1 + nota2) / 2;
     retorna resultado;
fimFuncao
 
FUNÇÃO MAIN
 

Todo programa em C consiste em uma ou mais funções, sendo a main a única função que necessariamente precisa estar presente em qualquer programa, pois ela é a primeira a ser chamada quando a execução do programa começa. Por se tratar de uma função, a main segue as mesmas regras de declaração de uma função. Também é chamada de função principal.

 
PARÂMETROS DE UMA FUNÇÃO
 

Existem duas maneiras de se passar dados para dentro de uma função, sendo elas conhecidas como: passagem por VALOR ou por REFERÊNCIA.

 
 
PASSAGEM DE PARÂMETROS POR VALOR
 

Quando uma função é chamada, a mesma função faz cópias dos valores enviados como parâmetros, dessa forma os valores originais não são alterados, pois a função manipula apenas as cópias dos mesmos.

 

Os valores existentes na função que foi chamada não podem ser acessados por outras funções, a menos que estes valores sejam enviados por parâmetros para outras funções, a partir da mesma, ou ainda retornados por ela. Todos os valores de uma função são apagados com o término da execução da mesma.

 
PASSAGEM DE PARÂMETROS POR REFERÊNCIA
 

Ao invés de se fazer uma cópia dos valores existentes na função principal, a função que é chamada leva como parâmetro o endereço de memória original das variáveis que ela manipulará durante sua execução, por meio dos parâmetros enviados a ela.

 

Neste tipo de passagem de parâmetros, o valor original da variável pode ser alterado, já que a função tem acesso ao seu endereço original, onde o dado manipulado esta realmente armazenado na memória do computador. Quando esta função é encerrada, o conteúdo enviado para ela não é destruído, pois ela somente recebeu o endereço original pertencente a outra função, normalmente a função principal, que só permitirá sua destruição quando ela for encerrada. Porém, quando uma função principal é encerrada o programa termina.

 

Exemplo:

 
    int calculo(int &valor);

     

        & - o "E comercial" na linguagem C é o operador de endereço e indica a
        manipulação ou uso do mesmo.
 
COMANDO RETURN
 

O comando return é usado na execução de duas ações na função, similar ao que já foi estudado no comando retorna em algoritmo. Este comando finaliza a função fazendo com que sua execução retorne à função chamadora e devolva um único valor existente dentro desta função para a função chamadora.

 

Todas as funções, com exceção as do tipo de dado void, retornam um único valor. Caso não exista nenhum comando return presente, o valor de retorno será tecnicamente indefinido (na maioria dos casos, os compiladores C devolvem ZERO quando não há nenhum valor de retorno especificado, mas isto não é recomendado para elaboração de programas eficientes). Uma função pode ter vários comandos return, mas somente um será executado realmente, pois após a sua execução ele encerra a função em execução e retorna para função chamadora, imediatamente.

 
PROCEDIMENTO X FUNÇÃO
 

Na linguagem C, procedimento corresponde a uma função sem retorno, como em algoritmo. Nesta linguagem não existe distinção entre função e procedimento, sendo ambos tratados como função, ou seja, um subprograma com lógica bem definida que pode ser acionada quantas vezes sejam necessárias para solucionar um problema.

 
 

O procedimento corresponde a uma função do tipo void (tipo de dado indefinido) que não possui o comando return devolvendo algum valor para a função chamadora. Desta forma se for preciso armazenar os dados coletados durante a execução da função pode-se recorrer a passagem de parâmetros por referência, uso de variáveis globais ou ainda alguns outros métodos que serão estudados mais adiante sobre esta linguagem de programação computacional.

 
VARIÁVEIS LOCAIS E GLOBAIS
 

As variáveis locais são variáveis que são declaradas dentro das funções. Somente as funções que as criaram podem utilizá-las, sendo que após o término da função, estas variáveis são destruídas (apagadas da memória do computador).

 
 

Exemplo:

 
/*
  SÍNTESE
     Objetivo: Determinar se um estudante foi aprovado ou reprovado
     Entrada: Média
     Saída: Mensagem informativa de "Aprovado" ou "Reprovado"
*/
#include <stdio.h>  
#include <conio.h> //de acordo com a versão do Dev-C pode ser usada <conio.c>
void main (void)
{   
   //Declarações     
      int situacao (float val);  //declaração de outra função (seu protótipo)
      float media;
      int verifica;      
   //Início
      printf("Informe a media do aluno");
      scanf("%f",&media);   //lê a média do aluno
      verifica = situacao(media);   //verifica recebe o resultado da função
      if(verifica == 1)
         puts("APROVADO");
      else
         puts("REPROVADO");
      getch();
      return(0);
}
 //Corpo da função situacao (descrição do que a função situacao faz
int situacao (float val)   //parâmetro VAL só existe dentro da função
{   //funcionando como uma variável local
  // Declarações
     int auxiliar;  //declaração de variável local - só existe dentro da função
  //Instruções
   if(val >= 7)
      auxiliar=1;
   else
      auxiliar=2;
   return(auxiliar);   //valor de auxiliar é retornado para função chamadora
}    
 /* Após a execução do comando return a variável auxiliar e o parâmetro
   val são apagados da memória, ou seja, são destruidos  */
 

Supondo uma execução, onde o usuário tenha informado o valor 8.9 para a variável media, observe o resultado do programa acima na tela a seguir:

 
 

As variáveis globais, ao contrário das locais, são declaradas fora de qualquer função (inclusive da função main), sendo seu conteúdo acessado por todas as funções que compõem o programa como um todo, pois tal variável (ou constante) é global e só será destruída da memória quando o programa terminar, ou seja, somente quando a função principal encerrar sua execução.

 

Exemplo:

 
/*
  SÍNTESE
     Objetivo: inicializar um vetor com um valor.
     Entrada: valor 
     Saída: vetor inicializado.
*/
#include <stdio.h>  
#include <conio.h>
void inicializaVetor(int vetor[],int valor);
void mostravetor( int vetor[]); //declarações globais dos procedimentos
int  TAMANHO = 5;  //declara�ao da variavel global
int main (void)
{
  //Declarações
      int vetor[5], valor;
  //Instruções
printf("Digite o valor para iniciar os elementos do vetor: " );
scanf("%d",&valor );
inicializaVetor(vetor, valor);	  // Passagem de parametros para o procedimento
mostravetor(vetor);	 // chamada do procedimento que mostra o vetor				
system("pause");
  return 0;
}

void inicializaVetor(int vetor[], int valor){ // procdimento que inicializa o vetor 
//Declara�oes locais 
  int i; 
// instrucoes 
  for ( i = 0; i < TAMANHO; i++) {
	   vetor[i] = valor;
	}
}
void mostravetor( int vetor[]){	 // procedimento que exibe o vetor 

//Declara�oes locais 
  int i; 
// instrucoes 
  puts(" ");
  printf("vetor: ");
  for ( i = 0; i < TAMANHO; i++) {
	  printf("%d  ", vetor[i]);
	}

}
/* Mesmo após o término da execução da função, o conteúdo de TAMANHO
             continua disponível na memória, pois estas variáveis são globais */
 

Supondo que o usuário informou o nome Carlos Henrique e o país Argentina, o resultado da execução seria:

 
 

O uso de variáveis globais não é recomendado, pois facilita a ocorrência de alguns problemas e dificulta a localização de erros no código fonte, além de não contribuir com a segurança no uso de funções (subprogramas em geral) devido as variáveis serem públicas durante toda a execução do programa, podendo serem alteradas a qualquer momento no mesmo.

 
FUNÇÃO CHAMANDO FUNÇÃO
 

Uma função pode chamar outras funções durante o seu funcionamento. Quando isso acontece, o funcionamento da função que chamou é interrompido e a função chamada entra em execução. Após seu término, o programa continua a execução de onde parou, neste caso, logo após a chamada de função.

 
 

Exemplo:

 
/*
  Síntese
    Objetivo: encontra a posição em que um valor estó dentro do vetor.
    Entrada: valor.
    Saída: posição em que o valor está e vetor ordenado.
*/
#include <stdio.h>
#include <stdlib.h>
int buscaBinaria(int vetor[],int valor,int tamanho);//protótipo da função

int main(void)
{
  //Declarações
  //inicializaçao do vetor com valores nao ordenados
  int vetor[14] = {10,20,8,9,15,1,0,80,32,60,2,3,4,5};  
  int tamanho = 14;  // tamanho do vetor 
  int valor,posicao,i;
  //Instruções
  printf("Digite o numero que deseja encontar:");
  scanf("%d",&valor );
 //chamanda da função que retona a poição do valor
  posicao = buscaBinaria(vetor,valor,tamanho);  
  if (posicao == -1){
    printf("valor nao encontrado\n");
  }else{
    printf("o valor procurado esta na posição: %d\n",posicao );
  }
   // imprime o vetor após a ordenaçãao
  printf("\n vetor ordenado: ");
  for(i = 0; i < tamanho ; i++){
    printf("%d ",vetor[i]);
  }
  getch();
  return 0;
}
 //======= FUNÇÕES E PROCEDIMENTOS ======

 void ordenaVetor(int vetor[],int tamanho){  //procedimento que ordena o vetor
 //Declarações locais
  int i,j,aux;
//instruções
  for ( i = 0; i < tamanho; i++) {
    for ( j = 0; j < tamanho - 1; j++) {
      if (vetor[j] > vetor[j+1] ){
        aux = vetor[j];
        vetor[j] = vetor[j+1];
        vetor[j+1] = aux;
      }
    }
  }
}
int buscaBinaria(int vetor[],int chave,int Tamanho){//função que faz a busca no vetor
//Declarações locais
     void ordenaVetor(int vetor[],int tamanho);
     int inferior = 0;     // limite inferior (o primeiro índice de vetor em zero)
     int superior = Tamanho-1; // limite superior (termina em um número a menos )
     int meio;
//instruções
     ordenaVetor(vetor,Tamanho);
     while (inferior <= superior)
     {
          meio = (inferior + superior)/2;
          if (chave == vetor[meio])
            return meio;
          if (chave < vetor[meio])
            superior = meio-1;
          else
            inferior = meio+1;
     }
     return -1;    // se o valor não for encontrado 
}
  

 
FUNÇÃO GLOBAL E FUNÇÃO LOCAL
 

Assim como as variáveis, as funções também podem ser globais e locais, onde as funções locais só podem ser acessadas pelas funções nas quais estão declaradas, enquanto as funções globais podem ser utilizadas por todas as funções que compõem o programa. As regras de declaração das variáveis aplicam-se também às funções e/ou procedimentos.

 

Observe no exemplo anterior que a função denominada buscaBinaria esta declarada fora de qualquer outra função, sendo ela então uma função global, porém a função ordenaVetor esta declarada dentro da função buscaBinaria, o que faz dela uma função local podendo ser acionada somente a partir da função buscaBinaria e seu retorno será também para ela (a função buscaBinaria).

 

Atividade de Fixação

 

No intuito de fixar a aprendizagem iniciada por meio deste módulo e verificar como seu entendimento sobre este conteúdo está, estão sendo sugeridos alguns exercícios de fixação para serem resolvidos. Clique no link de exercícios ao lado, pois será por meio dele iniciada a lista de exercícios sobre os conteúdos estudados até este momento nesta disciplina.