Contents

Capítulo 6 - Funções


botões
botões Conteúdo Capítulo anterior Capítulo seguinte

Um programa em linguagem C é essencialmente uma coleção de funções. Essas funções são muito semelhantes às que são possíveis de definir noutras linguagens.


Tópicos

setas
setas Up

Definição

O próprio programa principal em C é uma função - a função main(). No C não existe o conceito de procedimento, como existia no Pascal. Os procedimentos em C são também funções, com a particularidade de não retornarem valores.

A sintaxe geral para a definição de uma função é a seguinte:


tipo_de_retorno nome_da_função (def_parâmetro,def_parâmetro, ...)
  {
    variáveis_locais;
    instruções
  }

Por exemplo, uma função para calcular o valor médio de dois números, poderia ser definida da seguinte forma:

float average(float a, float b)
  {
    float ave;
  
    ave = (a + b) / 2;
    return ave;
  }

Esta função poderia ser chamada a partir da função main() como se mostra no exemplo seguinte:

void main(void)
{
  float a=5, b=15, result;

  result = average(a, b);
  printf("Média = %f\n", (double)result);
}

Repare-se na instrução de return na função, que além de a terminar é também a responsável pela definição do valor de retorno da mesma.

setas
setas Up

Funções void

As funções void são funções que não retornam qualquer valor e comportam-se, por isso, de forma equivalente aos procedimentos do Pascal.

Estas funções são definidas tendo como tipo de retorno a palavra void. A terminação pode fazer-se simplesmente pelo esgotar das instruções contidas na função (diz-se que ocorre uma situação de fall-through nessas circunstâncias) ou através de uma instrução de return sem a especificação de qualquer valor adicional. Geralmente este último tipo de terminação só é usado a meio das instruções da função (p. ex. dentro de um if).

A palavra void também deverá ser usada no lugar dos parâmetros se a função não tiver nenhum. Um exemplo:

void squares(void)
  {
    int k;
    for (k=1; k<=10; k++)
      printf("%d\n", k*k);
  }
void main(void)
  {
    squares();
  }
  

Na chamada de funções sem argumentos é sempre obrigatório utilizar parêntesis, sem nada lá dentro, como se vê acima.

setas
setas Up

Funções e arrays

É possível passar arrays como argumentos de funções. No entanto essa passagem tem um comportamento diferente dos outros tipos de variáveis.

Quando se passa qualquer outro tipo de variável como parâmetro de uma função, é inicialmente criada uma cópia dessa variável e a função atua sobre essa cópia sem poder modificar a variável original que foi passada (chama-se a esse mecanismo passagem por valor).

Quando se passa um array não se cria uma cópia; em vez disso é passado o endereço do primeiro elemento do array de forma automática e transparente para o utilizador. A consequência dessa forma de passagem é que os elementos do array que forem modificados na função mantêm essas modificações, mesmo depois de a função terminar.

Para arrays unidimensionais a passagem como parâmetro de uma função pode ser feita como no exemplo seguinte:

float average(int size, float list[])
  {
  int k;
  float sum = 0.0;

  for (k=0; k<size; k++)
    sum += list[k];
  return sum / size;
  }
  

No cabeçalho da função diz-se que o segundo argumento é um array de float's. Note-se que não é preciso especificar a sua dimensão na passagem como parâmetro. Compete ao programador assegurar que nunca é acedido um elemento para além da real dimensão do array.

Na passagem de arrays multidimensionais é necessários indicar todas as dimensões com exceção da primeira.

Exemplo:

void print_table(int x_size, int y_size, float table[][5])
  {
  int i, j;

  for (i = 0; i < x_size; i++)
    {
    for (j = 0; j < y_size; j++)
      printf("\t%f", (double) table[i][j]);
    printf("\n");
    }
  }

O parâmetro table é visto como um array de primeira dimensão desconhecida - chamemos-lhe n. Assim table é um array de n x 5. Novamente, compete ao programador assegurar que nunca é acedido um elemento para além das reais dimensões do array. O caractere '\t' é o caractere tab.

setas
setas Up

Protótipos

Em ANSI C, antes de se poder chamar uma função é necessário dar a conhecer ao compilador o seu tipo de retorno e o número e natureza dos seus argumentos.

Se a função que se chama estiver definida antes da chamada isso é suficiente. No caso contrário é necessário declarar um protótipo da função, a nível global e antes da sua chamada.

Um protótipo não é mais do que o cabeçalho da função seguido de ;. Estritamente não é necessário indicar no protótipo os nomes dos parâmetros, mas apenas os seus tipos (no entanto considera-se boa prática indicar também os nomes).

Embora não haja exigências quanto ao local de declaração dos protótipos (a não ser que tem de ser antes das chamadas) é de toda a conveniência agrupar os protótipos de todas as funções do programa (com a exceção de main) perto do seu início. Também, tornará mais fácil a leitura e interpretação do programa.

Exemplo de protótipo:

int strlen(char s[]);

O protótipo anterior indica que a função strlen() retorna um inteiro e aceita um parâmetro que é um array de caracteres (string).

setas
setas Up

Exercícios

  1. Escreva um programa que utilize uma função "replace" que aceite um array de caracteres (string - terminado com o caractere 0 (ou '\0')) como parâmetro e retorna um inteiro. A função substitui todos os espaços do seu parâmetro pelo caractere '-', e retorna o número de substituições feitas.
  2. Escreva um programa que leia texto do teclado, linha a linha, até chegar ao fim de texto (comandos CTRL-D ou CTRL-Z). O programa deverá escrever uma estatística do texto lido: número de palavras, número de linhas em branco, número total de linhas, número de letras. O programa deverá usar funções separadas para cada uma das suas tarefas. (Pode usar a função gets() de <stdio.h> para ler uma linha de texto do teclado - consulte o manual - por exemplo o manual do unix).
  3. Escreva um programa que calcule o salário semanal de um funcionário. As entradas são o número de horas usadas na semana e uma valorização da hora. Até 40 h/semana usa-se a valorização dada. Acima de 40h e até 60h há um bónus de 50%. Acima de 60h há um bónus de 100%. Use uma função para fazer os cálculos.
setas
setas Up