• Nenhum resultado encontrado

Até agora só temos usado procedimentos como ferramenta de modularização do código, mas muitas vezes é útil chamar um procedimento que retorna alguma informação de volta para o código que o chamou. Esta é a diferença entre procedimentos e funções: as funções retornam algum valor. Desta forma, as funções em linguagem C são similares às funções da matemática: uma função como

f : Z → Z, f(x) = x2+ 2

tem um parâmetro x (um inteiro), e retorna um determinado valor que depende do parâmetro passado; por exemplo,

f(5) = 52+ 2 = 27 É fácil escrever a mesma função em linguagem C:

int f(int x) { // 1x

return x * x + 2; // 2x

x

1 Definição da função f. A definição começa com int f(...), significando que o tipo de

retorno da função é int.

x

2 A palavra-chave return determina o valor de retorno da função f, que será o resultado da

expressão x * x + 2.

A função f do exemplo faz o mesmo que a versão matemática: dado o valor do parâmetro x, retorna um valor que é igual a x ao quadrado, somado a dois. Note que é preciso especificar o tipo do valor que é retornado pela função e, por isso, toda função começa com o tipo de retorno antes do nome. Especificar os tipos dos parâmetros e o tipo do valor de retorno também é similar às funções na matemática, para as quais devemos especificar os conjuntos domínio e contra-domínio.

5.3.1

Funções, Procedimentos e o Tipovoid

Neste ponto pode surgir uma pergunta: se é preciso especificar o tipo do valor retornado por uma função antes do nome da função (por exemplo int f(...)), por que nos procedimentos usa-se a palavra-chave void?

A verdade é que, embora algumas linguagens de programação façam uma distinção entre procedi- mentos e funções, na linguagem C existem apenas funções. Como a diferença entre procedimentos e funções é apenas o fato de retornar ou não um valor, os procedimentos em C são considerados funções que retornam um valor vazio. É isso que significa o void no início da definição de um procedimento como imprime_separador, que vimos anteriormente; a rigor, imprime_separador é uma função, mas retorna um valor vazio, ou seja, nenhum valor. O tipo void na linguagem C é um tipo especial que denota a ausência de valores.

Como procedimentos em C são funções, também é possível usar return em procedimentos, mas apenas para terminar sua execução e retornar imediatamente. Isso às vezes é útil para terminar um procedimento em pontos diferentes do seu final. Também pode-se utilizar return ao final do pro- cedimento, mas este uso é supérfluo e não é recomendado.

O seguinte exemplo demonstra o uso do return em procedimentos. Continuando no tema relaci- onado ao cálculo de médias, queremos detectar se uma das notas entradas pelo usuário é uma nota inválida antes de fazer o cálculo da média. Neste caso, o programa deve apenas imprimir se algum valor negativo foi entrado pelo usuário. O procedimento possui_negativo será responsável por imprimir uma mensagem caso um dos valores seja negativo.

Código fonte

Uso de return em um procedimento

1 #include <stdio.h> 2

3 void possui_negativo(float n1, float n2, float n3) { 4 if (n1 < 0.0) {

5 printf("Numero negativo encontrado!\n");

6 return; // 1x

7 }

8

9 if (n2 < 0.0) {

10 printf("Numero negativo encontrado!\n");

11 return;

13

14 if (n3 < 0.0) {

15 printf("Numero negativo encontrado!\n");

16 return;

17 }

18

19 printf("Nenhum numero negativo encontrado\n"); // 2x

20 }

21

22 int main() {

23 float nota1, nota2, nota3; 24

25 printf("Entre as três notas, separadas por espacos: "); 26 scanf("%f %f %f", &nota1, &nota2, &nota3);

27

28 possui_negativo(nota1, nota2, nota3); 29

30 printf("Media: %f\n", (nota1 + nota2 + nota3) / 3.0); 31

32 return 0;

33 }

x

1 Uso do return para sair prematuramente do procedimento.

x

2 Este comando de impressão será executado se nenhuma das condições testadas em

possui_negativo for verdade, ou seja, se nenhum dos valores dos parâmetros for nega- tivo.

Resultado de duas execuções do programa code/cap5/retorno_proc.c

Entre as três notas, separadas por espacos: 4.5 5.6 8.9 Nenhum numero negativo encontrado

Media: 6.333333

Entre as três notas, separadas por espacos: 4.5 -6.7 9.9 Numero negativo encontrado!

Media: 2.566667

O procedimento possui_negativo deve verificar se um dos três números passados como argu- mentos, mas basta achar um número entre eles para que o resultado possa ser impresso imediatamente e o procedimento pode retornar; por isso, usamos return assim que o primeiro valor negativo é en- contrado.

Esse exemplo ainda tem um problema: como pode ser visto nos exemplos de execução, mesmo que o usuário entre um valor negativo, a média aritmética das três notas ainda é impressa na tela (o usuário apenas é avisado que um dos valores foi negativo). Isso é uma indicação que seria melhor que possui_negativo fosse uma função, e que o programa principal verificasse o valor retornado e tomasse uma decisão. Se fizermos essas alterações ficamos com o seguinte programa:

Código fonte

1 #include <stdio.h> 2

3 int possui_negativo(float n1, float n2, float n3) { // 1x 4 if (n1 < 0.0 || n2 < 0.0 || n3 < 0.0) // 2x 5 return 1; // 3x 6 7 return 0; // 4x 8 } 9 10 int main() {

11 float nota1, nota2, nota3; 12

13 printf("Entre as três notas, separadas por espacos: "); 14 scanf("%f %f %f", &nota1, &nota2, &nota3);

15

16 if (possui_negativo(nota1, nota2, nota3) == 1) // 5x

17 printf("Nao e’ possivel calcular a media, uma ou mais notas ←-

sao negativas\n");

18 else

19 printf("Media: %f\n", (nota1 + nota2 + nota3) / 3.0); 20

21 return 0;

22 }

x

1 A função possui_negativo agora retorna um inteiro de valor 1 caso um dos valores dos

parâmetros seja negativo, e 0 caso contrário (todos são positivos).

x

2 Teste para identificar se um ou mais dos parâmetros informados são negativos.

x

3 A função retorna 1 se um dos números passados para a função for negativo.

x

4 Caso nenhum dos números seja negativo, o controle passa para o comando return ao final da

função e o valor 0 é retornado para indicar que nenhum número negativo foi encontrado.

x

5 O programa principal verifica o valor de retorno da função possui_negativo e imprime

informações adequadas na tela para cada caso.

Resultado de duas execuções do programa code/cap5/retorno_func.c

Entre as três notas, separadas por espacos: 6.8 9.7 -2.3 Nao e’ possivel calcular a media, uma ou mais notas sao ←-

negativas

Entre as três notas, separadas por espacos: 6.8 9.7 7.2 Media: 7.900000

Como pode-se ver nos dois exemplos de execução do programa, a saída agora é mais adequada. Caso uma das notas informadas seja negativa, o programa não imprime um valor de média, apenas avisando o usuário do erro na entrada de dados. O código da função possui_negativo também foi simplificado pelo uso do operador lógico OU.

Como funções e procedimentos são tratados de maneira uniforme na linguagem C (e em muitas outras linguagens atuais), a partir de agora vamos usar o termo função tanto para funções como para procedimentos. Isso não deve gerar nenhuma confusão. Em caso de dúvida, basta olhar para a definição da função no código-fonte do programa; se a função for declarada com o tipo de retorno void, então é um procedimento.

Documentos relacionados