Laboratório de Algoritmos – Aula 09A

Funções

Funções são conjunto de comandos agrupados, com a finalidade de executar determinada ação. Toda função recebe um nome que a define e através deste pode ser ativado.

Vantagens de se usar Funções

  • Permite o reaproveitamento de código;
  • Evita repetições de trechos de código dentro de um mesmo programa;
  • Facilita a manutenção do código, já que com o uso de funções é preciso alterar apenas a função que se deseja;
  • Facilita o entendimento do código, uma vez que programas muito grandes são mais difíceis de entender e dar manutenção;
  • Separa o programa em blocos que possam ser logicamente compreendidos de forma isolada.

Visão geral de arquivos na utilização de funções

visaogeralfuncao

Forma geral de uma Função

Tipo_de_Dado Nome_da_Funcao()
{
    Corpo da Função
}

Se nenhum tipo da dado é especificado, o compilador assume 
que o tipo de retorno da função é inteiro.

Exemplo:

//Exibe o menu de opções na tela
void MontaMenu()  
{
     system("cls");
     printf("LABORATÓRIO DE ALGORITMOS - LINGUAGEM C\n");
     printf("_______________________________________\n\n");
     printf("Digite a opcao desejada:\n\n");
     printf("[1] Conversao de temperatura\n");   
     printf("[2] Raiz quadrada de um numero\n");
     printf("[0] Sair\n\n"); 
}

Observação: void é um tipo de dado que não retorna valor algum.

Retorno de uma Função

O comando return é usado para retornar um valor de uma função. É também um comando de desvio, porque faz com que a execução retorne ao ponto em que a chamada da função foi feita.

Uma função pode ter mais de um comando return, porém a função irá parar  assim que ela encontre o primeiro return.

Exemplo:

int Quadrado()
{
    int numero;
    printf("Informe um numero2:");
    fflush(stdin);
    scanf("%d",&numero);
    
    return numero * numero;
}

Argumentos de Função (Parâmetros)

A Lista de Parâmetros é uma lista de nomes de variáveis com seus respectivos tipos de dados separados por virgula. Uma função pode não ter parâmetros e neste caso a lista é vazia, porém, mesmo assim os parenteses são necessários.

Exemplo:

Tipo_de_Dado Nome_da_Funcao(lista_de_parametros)
{
    Corpo da Função
}

Onde lista_de_parametros deve ser: 
    (tipo nomeVariavel1, tipo nomeVariavel2, …, tipo nomVariavelN)

Exemplo de Função com Parâmetro

O exemplo abaixo mostra uma função que recebe um parâmetro do tipo inteiro chamado idade. A função verifica se o valor do parâmetro é maior que 17 e retorna 1, caso seja verdade. Caso contrário 0.

int Quadrado(int numero);

int main(int argc, char *argv[])
{
    int numero;
    printf("Informe um numero:");
    fflush(stdin);
    scanf("%d",&numero);
    printf("O quadrado de %d e: %d", numero, Quadrado(numero));
    system("PAUSE>>NULL");	
    return 0;
}

int Quadrado(int numero)
{
    return numero*numero;
}

Dica – Sempre usar parâmetros

Uma função deve sempre procurar receber seus valores por parâmetros, ao invés de ler diretamente dados digitados pelo usuário (via scanf, gets, etc).

Fazendo isso suas função poderão ser sempre melhor reaproveitadas.

Além disso, uma função deve sempre ter um objetivo bem claro. Função que executam diversas tarefas devem ser quebradas em sub-funções. Isso facilita bastante manutenções futuras, já que melhora o entendimento e a visualização do programa.

Chamada (ou passagem) por Valor x Referência

Os argumentos de uma função, podem ser passados para sub-rotinas de duas maneiras.

A primeira é chamada por valor, sendo que neste, uma cópia da variável passada na invocação do método é passado para a função, de forma que alterações no valor do parâmetro, não interferem na variável passada como parâmetro na rotina principal.

A segunda forma é chamada por referência, sendo que o endereço de memória do parâmetro é passado para a sub-rotina. Desta forma, se o parâmetro é alterado na sub-rotina, seu valor também será alterado na função principal, que chamou a sub-rotina.

A forma mais comum de passagem de parâmetros é por valor.

PassagemPorValorXReferencia

Há vantagens e desvantagens na utilização de cada uma delas. Quando queremos por exemplo manipular variáveis de grande tamanhos (por exemplo de 1 GB), fazendo a passagem por valor, teríamos o tamanho dessa variável dobrada em memória. Pela passagem por referencia, como há o apontamento somente do endereço de memõria, o tamanho em memória permaneceria com o tamanho da variável inicial, economizando assim recursos.

Nas próximas aulas, serão vistas a passagem de valores por referencia com detalhes. Nesta aula, iremos ver somente a passagem de valores.

Protótipos de Funções

Protótipos de funções, trata-se da declaração da função feita no início do programa (antes da função main).

É possível criar e utilizar funções sem a definição de um protótipo da função, porém é uma boa prática criá-los, uma vez que quando usado, a linguagem C pode encontrar e apresentar quaisquer conversões de tipos ilegais entre o argumento usado para chamar uma função e a definição de seus parâmetros além de verificar possíveis diferenças entre o quantidades de argumentos declarados e passados.

Exemplo:

#include ...

//Protótipo da função
float ConvertePolCm(float tamanhoPolegadas);

int main(int argc, char *argv[])
{
    float tamanho;
      
    printf("\n\nInforme um tamanho em polegadas: ");
    fflush(stdin);
    scanf("%f",&tamanho);
    printf("\n%.2f pol. equivale a %.2f cm", 
                              tamanho, ConvertePolCm(tamanho));
    system("PAUSE>>NULL");	
    return 0;
}

float ConvertePolCm(float tamanhoPolegadas)
{
      return tamanhoPolegadas * 2.54;
}

Comando goto

O comando goto faz um desvido incondicional na sequencia de comandos a serem executados. O mesmo pode ser utilizado para simular um loop, ou até mesmo uma função.

Por boas práticas, a engenharia de software recomando a não utilização desse recurso, devido ao fato de que a lógica com muitas “idas e vindas” não seria uma boa maneira de escrever códigos, porém, quando a necessidade é velocidade de execução, é um recurso mais rápido do que funções.

Para sua utilização, é necessário declarar um label (marcador, com um nome qualquer, respeitando as regras de variáveis) seguindo de dois pontos, e posteriormente o comando goto apontando para o label.

Perceba que o comando de marcação (label) não interfere na execução de comandos.

Exemplo de goto simulando um loop:

exemplo_goto01

Exemplo de goto simulando uma função:

exemplo_goto02

Vida e escopo de variáveis

Quando programamos em uma única função (no nosso caso, estávamos digitando os comandos somente na função main), não conseguimos perceber que há o tempo de vida e visibilidade em diferentes locais de declaração de variáveis.

Com a utilização de funções, é possível verificar que mesmo declarando variáveis, não é possível utilizá-las em qualquer ponto do nosso programa.

Variáveis globais

As variáveis globais existem desde a sua declaração até a finalização do programa. É uma forma de se utilizar programas que possuem funções de um jeito mais simples.

A alteração de valores das variáveis globais em qualquer função comprometerá em todo o código. Portanto, tome muito cuidado ao utulizá-la.

exemplo_variavel_global.JPG

No caso mostrado, temos um código pequeno, a qual é muito fácil de se dar manutenção.  Caso tenhamos códigos mais complexos, será inevitável verificar em algum momento quais os valores que o seu programa está trabalhando.

Variáveis locais

As variáveis locais só existem dentro da função a qual ela foi declarada.

exemplo_variavel_local_erro

No código acima, o programa não irá compilar, devido as variáveis valo1 e valor2 estarem declaradas dentro da função main, a qual só existem dentro desta função. Como estamos tentando utilizar dentro da função somaValores, o compilador irá acusar erro por não estar delcarado as variáveis valor1 e valor2 na função somaValores.

Já no código abaixo, fizemos com que as variáveis valor1 e valor2 ficassem locais, porém estamos fazendo passagem de parametros (ou argumentos) por valor na utilização da função somaValores.

exemplo_variavel_local_correto

Dessa forma, podemos perceber que dentro da função somaValores, os valores de pValor1 e pValor2 são locais em relação a função somaValores.

Sempre que possível, tentar utilizar ao máximo o conceito de passagem de valores em funções. Dessa forma, é possível que seja evitado ao máximo a declaração de vairiáveis globais, que costumam a ter uma vida bem maior que variáveis locais.

Procedimentos versus Funções

Em outras linguagens de programação, como o Pascal e Visual Basic por exemplo, é muito comum trabalharmos com procedimentos e funções. A principal diferença entre estes é que um procedimento (ou procedure) é um bloco de código a qual não retorna valor quando é chamado. Já uma função, é necessario que se tenha o retorno de um valor conforme ela foi declarada na sua criação. Na linguagem C, só podemos utilizar funções (function), porém podemos fazer com que uma função tenha o papel de uma procedure, declarando em seu tipo como void. Caso não haja argumentos a serem passados, também é possível colocar a palavra void, a qual não é necessário ter nenhum comando return para este tipo de função.

Exemplo de Function utilizando o tipo Void

exemplo_funcaoVoid

Exemplo de Function utilizando return

exemplo_funcaoReturn

Observação: Conteúdo do material desenvolvido pelo Professor César Tofanini, adaptado pelo Professor Rodrigo Saito

.

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s