Menu

Funções em C++: declarar, definir e chamar (com exemplos)

Como escrever funções em C++: a anatomia de tipo de retorno/nome/parâmetros, declarações versus definições, retornar valores, funções void e armadilhas como esquecer o return ou o protótipo.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Por que as funções existem

Uma função é um bloco de código com nome que você pode executar quando quiser, chamando por ele. Em vez de repetir a mesma lógica em vários lugares, você a escreve uma vez, dá um nome a ela e chama esse nome onde for preciso. Isso deixa os programas mais curtos, mais fáceis de ler e mais fáceis de corrigir: você muda a lógica em um único ponto e todos que a chamam recebem a atualização.

Você já vem chamando uma função esse tempo todo: main. É o ponto de entrada do qual todo programa C++ começa. Agora você vai escrever as suas. Os laços que você viu antes, como o for baseado em intervalo, costumam viver dentro de funções para que você possa reutilizar todo um trecho de lógica pelo nome.

Anatomia de uma função

Toda função tem quatro partes: um tipo de retorno, um nome, uma lista de parâmetros entre parênteses e um corpo entre chaves.

int add(int a, int b) {   // tipo de retorno | nome | parâmetros
    return a + b;         // corpo
}
  • int é o tipo de retorno: o tipo de valor que a função devolve.
  • add é o nome que você usa para chamá-la.
  • (int a, int b) são os parâmetros: as entradas que quem chama fornece.
  • As chaves contêm o corpo, o código que roda quando você a chama.

Veja em um programa completo. Definir a função acima do main significa que o main consegue vê-la quando faz a chamada.

A chamada add(2, 3) executa a função com a = 2 e b = 3, e a expressão inteira se torna o valor retornado. Você pode armazená-lo em uma variável ou usá-lo diretamente dentro de outra expressão, como faz a segunda linha de cout.

Retornando um valor

A instrução return faz duas coisas: entrega um valor a quem chamou e encerra a função imediatamente. Qualquer código que venha depois de um return não é executado: o controle volta direto para o ponto onde a função foi chamada.

O tipo do valor retornado precisa coincidir com o tipo de retorno declarado (ou ser convertível para ele). Uma função declarada como int deve retornar um int; não retornar nada, ou sair pelo fim sem um return, é um bug em qualquer função que não seja void.

Funções void

Nem toda função produz um valor. Quando uma função apenas faz algo (imprime uma saída, atualiza um estado), seu tipo de retorno é void. Uma função void pode usar um simples return; para sair antes do tempo, ou simplesmente seguir até a chave de fechamento.

Tentar usar o resultado de uma função void (int x = greet("Ada");) é um erro de compilação, porque não há valor algum para atribuir. Um erro comum é escrever return someValue; dentro de uma função void; o compilador também rejeita isso.

Declarações versus definições

C++ lê um arquivo de cima para baixo, então, por padrão, uma função precisa aparecer antes do código que a chama. Quando essa ordem fica inconveniente, você divide a função em uma declaração (também chamada de protótipo) e uma definição.

Uma declaração informa a assinatura da função e termina com ponto e vírgula, sem corpo. Ela promete ao compilador "esta função existe; veja como chamá-la". A definição completa pode então vir depois, até mesmo após o main.

Sem o protótipo na linha 4, o compilador encontraria square(5) dentro do main antes de jamais ter visto square, e a compilação falharia. Os protótipos são também a forma como os arquivos de cabeçalho permitem que muitos arquivos-fonte compartilhem as mesmas funções. Observe que os nomes dos parâmetros em uma declaração são opcionais: int square(int); funciona igualmente bem; para o compilador, só os tipos importam.

Erros comuns

Algumas armadilhas pegam os iniciantes repetidamente:

  • Chamar antes de declarar. Se você receber o erro "add was not declared in this scope", a função está definida abaixo da sua primeira chamada e não tem protótipo. Suba a definição ou adicione um protótipo.
  • Esquecer de retornar. Chegar ao fim de uma função que não é void sem um return é comportamento indefinido: quem chamou recebe lixo. Compile com os avisos ativados (-Wall) e o compilador apontará isso.
  • Confundir definir com chamar. Uma definição tem um corpo entre chaves e nenhum ponto e vírgula no final. Uma declaração tem um ponto e vírgula e nenhum corpo. Misturá-las (como colocar um ponto e vírgula logo após a lista de parâmetros de uma função que você pretendia definir) gera erros confusos.
  • Ignorar o valor de retorno. add(2, 3); sozinho em uma linha compila, mas a soma calculada é silenciosamente descartada. Garanta que você realmente usa o que a função retorna.
// Parece uma definição, mas o ; perdido a transforma em uma
// declaração seguida de um bloco sobrando, um erro de digitação frequente:
int triple(int n);   // <- este ; encerra a instrução
{
    return n * 3;    // n não está definido aqui; este bloco ficou órfão
}

A seguir: parâmetros de função

Você viu que as funções recebem entradas por meio da sua lista de parâmetros, mas há muito mais nisso. A próxima página se aprofunda nos parâmetros de função: passagem por valor versus por referência, argumentos padrão, parâmetros const e como essa escolha afeta se a sua função pode ou não alterar os dados de quem a chamou.

Perguntas frequentes

Como se escreve uma função em C++?

Dê a ela um tipo de retorno, um nome, parênteses para os parâmetros e um corpo entre chaves: int add(int a, int b) { return a + b; }. Chame-a pelo nome com argumentos, como add(2, 3). Se a função não retorna nada, use void como tipo de retorno.

Qual é a diferença entre uma declaração e uma definição de função em C++?

Uma declaração (ou protótipo) informa ao compilador o nome, o tipo de retorno e os parâmetros de uma função, terminando com ponto e vírgula: int add(int a, int b);. Uma definição também fornece o corpo entre chaves. Você pode declarar uma função antes do main e defini-la mais tarde: a declaração permite chamá-la antes que a definição apareça.

O que acontece se uma função em C++ não retornar um valor?

Em uma função void, nada acontece: ela simplesmente termina. Mas em uma função que não é void, chegar ao fim sem um return é comportamento indefinido: quem chamou recebe um valor lixo e o programa pode se comportar mal. A maioria dos compiladores avisa sobre isso; sempre retorne um valor em todos os caminhos de uma função que não seja void.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR