Vimos na aula anterior o que são e como funcionam as funções na linguagem C. Hoje iremos aprender mais sobre os parâmetros de uma função.
Os parâmetros de uma função são valores externos que são passados para a função utilizar como variável local em seu escopo. Os parâmetros são de duas categorias: valor e referência.
Parâmetros por valor são a maneira default de se passar argumentos para uma função. Nesta categoria de parâmetro, é feita uma cópia da variável a ser passada para a função. Ou seja, a função não altera valores das variáveis externas, somente das variáveis internas (locais).
Logo, um parâmetro por valor pode ser tanto uma variável quanto uma constante.
Para definir que um parâmetro seja por valor, basta colocar o tipo daquele parâmetro como o tipo desejado.
void parametro_valor(int a, float b, char c){...}
Lembre-se de que os parâmetros por valor não alteram o valor da variável fora da função, observe.
#include < stdio.h > void param_valor(int x){ x += 2; printf("Dentro da funcao: %d\n", x); } int main(){ int x = 2; printf("Antes da funcao: %d\n", x); param_valor(x); printf("Fora da funcao: %d\n", x); return 0; }Code Execution
O programa a seguir lê um número n e em seguida lê n números, informando se o mesmo é par e maior que 20, par e menor ou igual a 20 ou impar.
#include < stdio.h > int check(int x){ if(x%2 == 0){ if(x > 20) return 1; return 0; } return -1; } int main(){ int n,i,y, resp; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d", &y); resp = check(y); if(resp == 1) printf("%d eh par e maior que 20\n",y); else if(resp == 0) printf("%d eh par e menor ou igual a 20\n",y); else printf("%d eh impar\n",y); } return 0; }Download Code
Exemplo no Terminal
APC$ gcc -o valor -std=c11 valor.c APC$ ./valor 4 1 1 eh impar 20 20 eh par e menor ou igual a 20 25 25 eh impar 26 26 eh par e maior que 20
Os parâmetros por referência não são uma cópia do argumento a ser passado, mas uma referência para este. Ou seja, parâmetros por referência na verdade são ponteiros para as variáveis passadas.
Logo, eles só podem ser usados com variáveis.
Para definir que um parâmetro seja por valor, deve-se colocar o tipo daquele parâmetro como um ponteiro para o tipo desejado.
void parametro_referência(int* a, float* b, char* c){...}
Lembre-se de que funções com parâmetros por referência alteram as variáveis externas à função. Observe.
#include < stdio.h > /* Lembre-se que operacoes com ponteiros sao um pouco diferentes. */ void param_ref(int* x){ *x += 2; printf("Dentro da funcao: %d\n", *x); } int main(){ int x = 2; printf("Antes da funcao: %d\n", x); param_ref(&x); printf("Fora da funcao: %d\n", x); return 0; }Code Execution
O programa a seguir realiza o mesmo papel do programa anterior porém a diferença é que há uma passagam de valor por referência
#include < stdio.h > /* Note que esta função é do tipo void, enquanto a mesma função com parâmetro de valor precisava ser do tipo int */ void check(int x, int *resp){ if(x%2 == 0){ if(x > 20) *resp = 1; else *resp = 0; } else *resp = - 1; } int main(){ int n,i,y, resp; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d", &y); check(y, &resp); if(resp == 1) printf("%d eh par e maior que 20\n",y); else if(resp == 0) printf("%d eh par e menor ou igual a 20\n",y); else printf("%d eh impar\n",y); } return 0; }Download Code
Exemplo no Terminal
APC$ gcc -o referencia -std=c11 referencia.c APC$ ./referencia 4 1 1 eh impar 20 20 eh par e menor ou igual a 20 25 25 eh impar 26 26 eh par e maior que 20
Uma funçao em C só pode retornar 1 valor, de qualquer tipo. Existem algumas maneiras de conseguir "retornar" mais de um valor no entanto, e uma delas é com ponteiros.
Podemos tomar vantagem do fato que parâmetros por referência, em uma função, referenciam uma variável externa à função e utilizar esses ponteiros para alterar o valor destas variáveis dentro da função. Desta forma, ao final da execução da função o valor destas variáveis terá sido alterado, fazendo parecer que a função "retornou" esses valores também.
Este não é um uso tão comum, no entanto, pois causa efeitos colaterais que podem ser difíceis de detectar, uma vez que este "retorno" não é explícito.
#include <stdio.h> #include <math.h> /* Esta função retorna o valor de delta de uma função quadratica. Se a função tiver raízes reais, elas também são "retornadas". Parâmetros por valor: a, b, c. As constantes reais da função. Parâmetros por referência: x1 and x2. Referência para as variáveis onde as raízes devem ser armazenadas, se existirem. */ double baskara(double a, double b, double c, double* x1, double* x2){ double delta = b*b - 4*a*c; if (delta > 0){ /* Assigns solutions of function, if they exist */ *x1 = (-b + sqrt(delta))/(2*a); *x2 = (-b - sqrt(delta))/(2*a); } return delta; } int main(){ double a,b,c,x1,x2; printf("Função com raizes reais\n"); a = 1; b = -3; c = 1; x1 = 0; x2 = 0; /* Note que x1 e x2 são parâmetros de referência */ double delta = baskara(a, b, c, &x1, &x2); printf("Delta: %.2lf\n", delta); /* Note que o valor de x1 e x2 nao eh mais 0 */ printf("X1: %.2lf\nX2: %.2lf\n", x1, x2); printf("===============\n"); printf("Função sem raizes reais\n"); a = 1; b = 3; c = 3; x1 = 0; x2 = 0; delta = baskara(a, b, c, &x1, &x2); printf("Delta: %.2lf\n", delta); /* Note que o valor de x1 e x2 ainda eh 0 */ printf("X1: %.2lf\nX2: %.2lf\n", x1, x2); return 0; }Download Code
Executando o código acima temos a seguinte saída abaixo. Note que não aletamos o valor de x1 e x2 na função main para a função com raízes reais. Esses valores foram alterados pela função baskara.
Obs: Note que na linha de compilação foi usada a flag -lm. Ela é necessária para utilizar funções da biblioteca math.h. A função sqrt é desta biblioteca.
APC$ gcc -lm -o baskara -std=c11 baskara.c APC$ ./baskara Função com raizes reais Delta: 5.00 X1: 2.62 X2: 0.38 =============== Função sem raizes reais Delta: -3.00 X1: 0.00 X2: 0.00