Capítulo 6 - Funções


Conteúdo 

Capítulo anterior 

Capítulo seguinte 

Um programa em linguagem C é, como já se disse, essencialmente uma coleção de funções. Essas funções são muito semelhantes às que são possíveis de definir em outras linguagens como o Pascal. 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 coisa alguma.


Tópicos



Definição

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 depois ser chamada 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.
 

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.
 

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 usuário. 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 da 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 dimensão quando da passagem como parâmetro. Compete ao programador assegurar de forma absoluta que nunca é acessado um elemento fora 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 de forma absoluta que nunca é acessado um elemento fora das reais dimensões do array. O carácter '\t' é o carácter tab.
 

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, a nível global e antes da chamada, um protótipo da função. 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 excepção de main) perto do seu início. Isso tornará a leitura e interpretação do programa bastante mais fácil.

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).
 

Up


Exercícios

Veja aqui os exercícios 

Up


[REV 04/2000]