C++: Fundamentos de Funções
Última atualização: 2026-08-26
Nas aulas anteriores, todo código era escrito dentro da função
main.Mas à medida que os programas crescem, a função
mainfica longa e difícil de manter.Funções resolvem este problema — dividindo o código em pequenos módulos, cada um responsável por uma tarefa.
1. O que é uma Função?
(1) 1.1 Funções no Dia a Dia
| Cenário da vida real | Equivalente em programação |
|---|---|
| Você pressiona o botão "ligar" no controle remoto da TV | Chamar a função turnOnTV() |
| A TV automaticamente realiza uma série de operações (ligar, buscar canais, exibir imagem) | O código dentro do corpo da função |
| Você não precisa saber como a TV funciona internamente | A propriedade de "encapsulamento" das funções |
Uma função é um bloco de código que executa uma tarefa específica, que você pode chamar repetidamente.
(2) 1.2 Por Que Precisamos de Funções?
Sem funções (exemplo ruim):
#include <iostream>
int main() {
// Calcular área do primeiro retângulo
double width1 = 5.0, height1 = 3.0;
double area1 = width1 * height1;
std::cout << "Area 1: " << area1 << std::endl;
// Calcular área do segundo retângulo
double width2 = 7.0, height2 = 2.5;
double area2 = width2 * height2;
std::cout << "Area 2: " << area2 << std::endl;
// Calcular área do terceiro retângulo
double width3 = 4.0, height3 = 6.0;
double area3 = width3 * height3;
std::cout << "Area 3: " << area3 << std::endl;
return 0;
}
Com funções (exemplo bom):
#include <iostream>
// Define a função
double calculateArea(double width, double height) {
return width * height;
}
int main() {
std::cout << "Area 1: " << calculateArea(5.0, 3.0) << std::endl;
std::cout << "Area 2: " << calculateArea(7.0, 2.5) << std::endl;
std::cout << "Area 3: " << calculateArea(4.0, 6.0) << std::endl;
return 0;
}
Comparação:
| Sem Funções | Com Funções |
|---|---|
| Duplicação de código (copiar e colar) | Reutilização de código (escrever uma vez) |
| Mudar lógica requer mudanças em múltiplos lugares | Apenas mudar o corpo da função em um lugar |
| Difícil de manter | Fácil de manter |
2. Definição de Função
(1) 2.1 Sintaxe Básica
ReturnType functionName(parameterList) {
// corpo da função
return returnValue; // se o tipo de retorno não for void
}
(2) 2.2 Partes de uma Função
| Parte | Significado | Exemplo |
|---|---|---|
| Tipo de retorno | O tipo de valor que a função retorna | int, double, void (sem retorno) |
| Nome da função | O nome da função (segue regras de nomenclatura de variáveis) | calculateArea, printHello |
| Lista de parâmetros | As entradas que a função recebe (pode ser vazia) | (double w, double h) |
| Corpo da função | O código que a função executa | { return w * h; } |
| return | Retorna o resultado ao chamador | return area; |
▶ Exemplo 1: Definir uma Função Simples (Dificuldade ⭐)
#include <iostream>
// Definição da função: calcular a soma de dois números
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(3, 5); // Chamar a função
std::cout << "3 + 5 = " << result << std::endl;
return 0;
}
Saída:
3 + 5 = 8
3. Chamadas de Função
(1) 3.1 Sintaxe de Chamada
functionName(argumentList);
| Termo | Significado | Exemplo |
|---|---|---|
| Definição de função | Escrever o código da função | int add(int a, int b) { ... } |
| Chamada de função | Usar a função | add(3, 5); |
| Parâmetro formal (parâmetro) | Parâmetros na definição da função | int a, int b |
| Parâmetro real (argumento) | Valores passados ao chamar a função | 3, 5 |
💡 Ponto-chave: Argumentos são copiados para os parâmetros (aprenderemos sobre referências mais tarde, onde a cópia não é necessária).
4. Valores de Retorno
(1) 4.1 A Instrução return
return tem dois propósitos:
- Retornar um resultado ao chamador
- Encerrar a função (código após return não será executado)
#include <iostream>
int max(int a, int b) {
if (a > b) {
return a; // Encerra função, retorna a
} else {
return b; // Encerra função, retorna b
}
std::cout << "This line never executes" << std::endl; // Código morto
}
int main() {
std::cout << "Maximum: " << max(10, 20) << std::endl;
return 0;
}
(2) 4.2 Funções Sem Valor de Retorno (void)
Se uma função não precisa retornar um valor, use void como tipo de retorno:
#include <iostream>
void printWelcome() { // void significa sem valor de retorno
std::cout << "========== Welcome ==========" << std::endl;
std::cout << "This is a void function, no return needed" << std::endl;
}
int main() {
printWelcome(); // Chamar função void, não precisa receber valor de retorno
return 0;
}
💡 Dica: Você também pode escrever return; (sem um valor) em uma função void para sair antecipadamente.
void printIfPositive(int x) {
if (x <= 0) {
return; // Sai da função antecipadamente
}
std::cout << x << " is positive" << std::endl;
}
5. Protótipos de Função (Declarações de Função)
(1) 5.1 O Problema: Funções Devem Ser Definidas Antes de Serem Chamadas
#include <iostream>
int main() {
std::cout << add(3, 5) << std::endl; // ❌ Erro: compilador ainda não viu a definição de add
return 0;
}
int add(int a, int b) {
return a + b;
}
Mensagem de erro de compilação:
error: 'add' was not declared in this scope
(2) 5.2 Solução: Protótipos de Função
Um protótipo de função (também chamado de declaração de função) diz ao compilador "tal função existe", enquanto o corpo da função real pode ser definido depois.
#include <iostream>
int add(int a, int b); // Protótipo de função (termina com ponto e vírgula!)
int main() {
std::cout << add(3, 5) << std::endl; // ✅ Compilador sabe que add existe
return 0;
}
int add(int a, int b) { // Definição da função
return a + b;
}
💡 Regras:
- Protótipos de função terminam com ponto e vírgula
- Nomes de parâmetros podem ser omitidos, apenas tipos necessários:
int add(int, int); - Mas é recomendado manter os nomes dos parâmetros para legibilidade
6. Prática: Calculadora com Funções
▶ Exemplo 2: Calculadora Usando Funções (Dificuldade ⭐⭐)
#include <iostream>
#include <iomanip>
// Protótipos de funções
double add(double a, double b);
double subtract(double a, double b);
double multiply(double a, double b);
double divide(double a, double b);
int main() {
double num1, num2;
char op;
std::cout << "Please enter the first number: ";
std::cin >> num1;
std::cout << "Please enter an operator (+ - * /): ";
std::cin >> op;
std::cout << "Please enter the second number: ";
std::cin >> num2;
std::cout << std::fixed << std::setprecision(2);
switch (op) {
case '+':
std::cout << "Result: " << add(num1, num2) << std::endl;
break;
case '-':
std::cout << "Result: " << subtract(num1, num2) << std::endl;
break;
case '*':
std::cout << "Result: " << multiply(num1, num2) << std::endl;
break;
case '/':
if (num2 != 0) {
std::cout << "Result: " << divide(num1, num2) << std::endl;
} else {
std::cout << "Error: Divisor cannot be 0!" << std::endl;
}
break;
default:
std::cout << "Error: Unsupported operator!" << std::endl;
break;
}
return 0;
}
// Definições das funções
double add(double a, double b) {
return a + b;
}
double subtract(double a, double b) {
return a - b;
}
double multiply(double a, double b) {
return a * b;
}
double divide(double a, double b) {
return a / b;
}
Saída:
Please enter the first number:
Please enter an operator (+ - * /):
Please enter the second number:
Result:
Result:
Result:
Result:
Error: Divisor cannot be 0!
Error: Unsupported operator!
7. Erros Comuns
(1) 7.1 Esquecer de Escrever um Protótipo de Função
Erro:
int main() {
foo(); // ❌ Compilador não sabe o que é foo ainda
return 0;
}
void foo() {
std::cout << "Hello" << std::endl;
}
Correção: Adicione um protótipo de função:
void foo(); // ✅ Protótipo de função
int main() {
foo();
return 0;
}
void foo() {
std::cout << "Hello" << std::endl;
}
(2) 7.2 Protótipo e Definição Não Correspondem
Erro:
int foo(int a); // Protótipo: retorna int
int main() {
foo(5);
return 0;
}
double foo(int a) { // ❌ Erro: definição retorna double, não corresponde ao protótipo
return a + 0.5;
}
(3) 7.3 Esquecer de Escrever return
Erro:
int add(int a, int b) {
int sum = a + b;
// ❌ Esqueceu de escrever return
}
int main() {
int result = add(3, 5);
std::cout << result << std::endl; // Exibe valor lixo
return 0;
}
💡 Dica: O compilador C++ pode não alertar sobre um return ausente, mas o comportamento do programa é indefinido (pode exibir lixo, pode travar).
❓ Perguntas Frequentes
P: Nomes de parâmetros podem ser omitidos em protótipos de função? R: Sim, mas é recomendado mantê-los.
int add(int, int);é sintaticamente válido;int add(int a, int b);é recomendado para legibilidade. P: Uma função pode retornar múltiplos valores? R: Uma função C++ só pode ter um valor de retorno. Mas você pode "retornar" múltiplos valores usando: 1. Parâmetros de ponteiro ou referência (cobertos mais tarde) 2. Retornando uma struct ou classe (coberto mais tarde) 3. Usandostd::tuple(C++11 e posterior) P: Posso escrever return em uma função void? R: Sim!return;(sem um valor) pode sair de uma funçãovoidantecipadamente. P: Por que minha função definida depois de main compila com sucesso? R: O compilador pode ser "leniente", ou você pode ter inadvertidamente escrito um protótipo de função. Recomendação: sempre coloque protótipos de função antes de main e definições depois (ou ambos antes).
▶ Exemplo 3: Valor de Retorno de Função (Dificuldade ⭐)
#include <iostream>
int max(int a, int b) {
return (a > b) ? a : b;
}
int main() {
int x = 10, y = 20;
std::cout << "Larger value: " << max(x, y) << std::endl;
return 0;
}
Saída:
Larger value: 20
return. O operador ternário ? : pode simplificar verificações condicionais simples.
📖 Resumo
- Funções são blocos de código que executam tarefas específicas e podem ser reutilizados
- Sintaxe de definição de função:
ReturnType functionName(parameterList) { functionBody } - Protótipos de função dizem ao compilador que uma função existe, terminando com ponto e vírgula
returnretorna um resultado e encerra a função- Funções
voidnão retornam um valor - Funções podem ser declaradas primeiro (protótipo) e definidas depois
📝 Exercícios
-
Básico (Dificuldade ⭐): Escreva uma função
int multiply(int a, int b)que retorne o produto de dois inteiros. Chame-a na funçãomain. -
Intermediário (Dificuldade ⭐⭐): Escreva uma função
bool isPrime(int n)que determine se um inteiro é primo. -
Primo: um número divisível apenas por 1 e por ele mesmo (ex: 2, 3, 5, 7, 11)
-
Na função
main, deixe o usuário digitar um inteiro, chameisPrime, e exiba o resultado -
Desafio (Dificuldade ⭐⭐⭐): Escreva um programa com as seguintes funções:
-
int fibonacci(int n): retorna o n-ésimo número de Fibonacci -
void printFibonacci(int n): exibe os primeiros n números de Fibonacci
Na função main, deixe o usuário digitar n, primeiro exiba os primeiros n números, depois exiba o valor do n-ésimo número.
- Funções são blocos de código reutilizáveis que reduzem repetição
- Quatro elementos da função: tipo de retorno, nome da função, lista de parâmetros, corpo da função
- Declarações de protótipo de função permitem que o compilador saiba que a função existe
- return retorna um valor e encerra a execução da função
- Funções void não retornam valor; podem usar return; para sair antecipadamente
8. 🚀 Próximo Passo
Agora que você aprendeu fundamentos de funções, a seguir vamos aprender passagem de parâmetros de função (Aula 11) — aprendendo como passar parâmetros para funções e a diferença entre "passagem por valor" e "passagem por referência".