Quaddro + MacMagazine: programando em C — funções

Declarando uma função no Xcode

Depois dos conceitos iniciais, trabalhos com variáveis, condicionais e repetidores, chegamos agora a mais um importante fundamento da programação: funções.

Pré-requisitos

Intro, da banda The xx

Conceitos

A premissa de uma função nos dá uma boa ideia da sua aplicabilidade: reutilização. Criamos funções como um grupo de códigos que podem ser facilmente reaproveitados em outros momentos.

Imagine por exemplo que você criou uma rotina que recebe um valor e calcula um frete ou um imposto — vamos supor, umas 3 linhas de código. Agora imagine que esse cálculo será necessário em 10 situações do seu programa. A abordagem mais fácil é o famoso “copia e cola” das linhas de códigos, mas nesse caso você estaria gerando 30 linhas de código desnecessárias.

É nesse contexto que se encaixam perfeitamente as funções. A ideia é que todos os códigos da nossa rotina fiquem contidos dentro de um bloco definido por um nome. A partir daí, toda vez que nós precisarmos desse código basta usar o nome da função que o contém.

Comparando com o exemplo passado, em vez das 30 linhas de cópias, usando funções você teria aproximadamente 15 linhas. Outro problema de ficar copiando e colando blocos iguais de código é que, se por algum motivo algo precisar ser alterado, começa a caça as replicatas para adequações também.

Acho que deu para perceber o quão úteis são as funções, certo?! Então vamos à prática.

Prática

De certa forma nós estamos trabalhando com funções desde o primeiro artigo de C, quando eu ensinei o uso do printf, uma vez que ele é uma função de sistema que possui internamente uma série de comandos, então vamos pegar essa função familiar para que eu possa explicar algumas coisas.

Quando nós começamos vocês devem se lembrar que, em um determinado momento, eu apaguei o include do stdio, o que gerou um alerta no Xcode. A ideia é simples: para rodar uma função no código o Xcode precisa conhecê-la, e naquele caso o include é o “apresentador”.

Agora como a ideia é criar uma função personalizada nossa, não temos o include para carregar algo pronto, mas sim a definição do zero da nossa própria função. Criem um novo projeto chamado Trabalho_Funcoes e definam a seguinte estrutura:

Declarando uma função no Xcode

Analisando o código, percebemos algumas coisas importantes:

  1. Não é regra (principalmente nos compiladores mais modernos), mas fizemos a definição da nossa função antes da função padrão main.
  2. Por boa prática (e para alinhar alguns conceitos com Objective-C em textos futuros), antes de definir o que a função faz nós declaramos seu protótipo. A ideia é “preparar” o compilador para o que está por vir.
  3. Depois de declarar o protótipo estamos prontos para a definição em si, que agrupa entre as chaves quais códigos deverão ser executados.
  4. Para executar os códigos definidos na função, basta chamá-la de maneira direta pelo seu nome.

Após essas constatações iniciais sobre o código acima, vamos analisar a parte de sintaxe dessa declaração. O primeiro ponto aqui é aquele void antes do nome da função e também dentro dos parênteses, vamos por partes.

Lembrando o nosso primeiro texto sobre variáveis, os elementos na linguagem C precisam ter um tipo de dado explícito. Isso quer dizer que, se uma variável tem tipo de dado, uma função também terá. A diferença aqui é que o tipo da função na verdade refere-se ao que a função retorna.

Voltem ao código e analisem a diferença dessa função para a padrão main. Percebam que a main é do tipo int e por isso contém o comando return usando um número inteiro (no caso, 0). A regra aqui é simples e direta: o tipo de dado de uma função é atrelado ao tipo de valor definido no comando return dentro dessa função. Se uma função retorna um número inteiro, seu retorno será int. Se uma função retorna um número quebrado, seu retorno será float. Aí, você pergunta: “Danilo, e quando a função não retornar nada?” É aí que usamos o void! Toda função que não tem retorno e por consequência não usa o comando return é do tipo void. Sacaram?!

Avançando temos o segundo void da nossa função, ele está dentro dos parênteses. Os parênteses de uma função definem os chamados parâmetros ou argumentos. A ideia é permitir o uso de algum valor complementar, se a função precisar. Um exemplo é a função quit (fechar), que não precisa de complemento uma vez que fechar é fechar. Agora uma função como setVolume (definir volume) precisaria de um valor para ser usado e aí entra o parâmetro.

Mais uma vez, aparece o void quando não há parâmetros. Nas abordagens modernas esse void não é obrigatório, mas para fixar a ideia do “vazio” ou quero mantê-lo. Com isso temos a sintaxe básica para declarar uma função:

tipoRetorno nomeFunção (parâmetros)

A definição do que a função faz fica dentro dos parênteses e no nosso caso definimos a exibição de um simpático “Oi”. Toda vez que a função for chamada (outro termo usado para a execução de uma função), esse código é disparado.

Para falar mais do tipos de retornos e parâmetros, vou criar mais uma função demonstrada na imagem abaixo:

Função dobro no Xcode

Notem que, novamente, primeiro eu defini o protótipo da função explicando ao compilador qual é o nome e tipos de dados, para depois fazer a definição em si.

Nesse caso a função recebe um número via parâmetro e devolve o resultado da conta do dobro (percebam que, como usei return, a função é diferente de void). Um comentário pertinente é que, no caso de funções com retorno, podemos usar a chamada como se estivéssemos usando um valor comum.

Isso quer dizer que, como a função retorna um inteiro, eu posso usá-la como se fosse propriamente um número em uma expressão. Atentem que eu inseri dentro da chamada da função printf a execução da nossa função dobro (cuidado com o fechamento dos parênteses).

Dessa forma fica claro que, ao usar uma função com retorno, estamos na verdade trabalhando diretamente com o valor que será devolvido, portanto os cuidados com tipagem (e especificadores de formato) continuam.

Vamos ao desafio para vocês exercitarem o trabalho com funções.

» DESAFIO 1: FUNÇÃO DE SOMA

Você deve criar uma função que receba dois valores inteiros e retorne o resultado da soma entre eles. Após implementar a função defina a sua execução dentro de um printf resultando na seguinte mensagem:

Desafio de funções

» DESAFIO 2: CÁLCULO DE IMC

Você deverá criar uma função que receba dois parâmetros (peso e altura) e retorne o cálculo de IMC. Após calcular o IMC você deve retornar seu valor e faixa de classificação. Essa detecção de classificação usará um condicional com o resultado do IMC.


Fórmula: IMC = peso / altura²


Tabela de Classificação

ResultadoSituação
Abaixo de 17Muito abaixo do peso
Entre 17 e 18,49Abaixo do peso
Entre 18,5 e 24,99Peso normal
Entre 25 e 29,99Acima do peso
Entre 30 e 34,99Obesidade I
Entre 35 e 39,99Obesidade II (severa)
Acima de 40Obesidade III (mórbida)

A imagem a seguir ilustra o fluxo de mensagens e utilização:

Desafio de funções

·   ·   ·

Esses desafios serão um bom estudo para fixação dos conceitos. Seguindo uma sugestão do leitor Bruno Valente Pimentel, os códigos do programa deste artigo serão disponibilizados no post oficial do fórum da Quaddro, que vocês podem usar também para postar dúvidas ou soluções desses desafios.

E antes que eu me esqueça: preparem-se para os futuros textos, o Objective-C está chegando! 😛

Posts relacionados