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
- Trabalhar com variáveis;
- Conhecer a estruturas condicionais;
- Conhecer estruturas de repetição: FOR, WHILE e DO WHILE.
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:

Analisando o código, percebemos algumas coisas importantes:
- Não é regra (principalmente nos compiladores mais modernos), mas fizemos a definição da nossa função antes da função padrão
main
. - 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.
- 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.
- 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:

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 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
Resultado | Situação |
---|---|
Abaixo de 17 | Muito abaixo do peso |
Entre 17 e 18,49 | Abaixo do peso |
Entre 18,5 e 24,99 | Peso normal |
Entre 25 e 29,99 | Acima do peso |
Entre 30 e 34,99 | Obesidade I |
Entre 35 e 39,99 | Obesidade II (severa) |
Acima de 40 | Obesidade III (mórbida) |
A imagem a seguir ilustra o fluxo de mensagens e utilização:
· · ·
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! 😛