![]() |
![]() |
![]() |
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.
![]() |
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.
![]() |
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.
![]() |
É 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.
![]() |
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).
![]() |
![]() |