C++: Passagem de Parâmetros de Função

Última atualização: 2026-08-26

Na Aula 10 aprendemos fundamentos de funções e como funções podem receber parâmetros.

Mas como exatamente os parâmetros são passados para as funções? Se um parâmetro é modificado dentro da função, a variável externa muda?

É isso que esta aula cobre — métodos de passagem de parâmetros.


1. Passagem por Valor

(1) 1.1 Uso Básico

Passagem por valor é o método padrão de passagem de parâmetros em C++ — o valor do argumento é copiado para o parâmetro.

CPP
#include <iostream>

void modifyValue(int x) { // x é um parâmetro (cópia)
 x = 100; // Modifica a cópia, não afeta a variável original
 std::cout << "x in function = " << x << std::endl;
}

int main() {
 int a = 5;
 modifyValue(a); // Passagem por valor: o valor de a é copiado para x
 std::cout << "a in main = " << a << std::endl; // a ainda é 5
 return 0;
}

💡 Ponto-chave: Com passagem por valor, modificar o parâmetro dentro da função não afeta o argumento.

(2) 1.2 Prós e Contras da Passagem por Valor

Prós Contras
Seguro (a função não pode modificar o argumento) Objetos grandes são caros para copiar (ex: arrays grandes, structs grandes)
Lógica clara Não permite que a função "retorne" múltiplos valores


2. Passagem por Ponteiro

Se você quer que uma função modifique uma variável externa, pode passar seu endereço (ponteiro).

(1) 2.1 Uso Básico

CPP
#include <iostream>

void modifyValue(int* x) { // x é um ponteiro
 *x = 100; // Desreferência: modifica o valor que o ponteiro aponta
 std::cout << "*x in function = " << *x << std::endl;
}

int main() {
 int a = 5;
 modifyValue(&a); // Passa endereço: passa o endereço de a para a função
 std::cout << "a in main = " << a << std::endl; // a agora é 100
 return 0;
}

💡 Ponto-chave: Com passagem por ponteiro, a função pode modificar o valor do argumento através do ponteiro.

(2) 2.2 Por Que Pode Modificar?

Passo Explicação
1 int a = 5; — Aloca espaço na memória e armazena 5
2 modifyValue(&a); — Passa o endereço de a para a função
3 int* x recebe o endereço, apontando para o espaço de memória de a
4 *x = 100; — Modifica o valor de a através do ponteiro


3. Passagem por Referência

C++ introduziu referências — elas são "apelidos" para variáveis, mais seguras e fáceis de usar que ponteiros.

(1) 3.1 Uso Básico

CPP
#include <iostream>

void modifyValue(int& x) { // x é uma referência (apelido)
 x = 100; // Modificar x modifica a variável original
 std::cout << "x in function = " << x << std::endl;
}

int main() {
 int a = 5;
 modifyValue(a); // Passagem por referência: não precisa de &, parece passagem por valor
 std::cout << "a in main = " << a << std::endl; // a agora é 100
 return 0;
}

💡 Ponto-chave: Com passagem por referência, o parâmetro é um apelido do argumento — modificar o parâmetro modifica o argumento.

(2) 3.2 Referência vs Ponteiro

Comparação Referência Ponteiro
Sintaxe int& x = a; int* x = &a;
Pode ser nulo ❌ Não (deve ser inicializado) ✅ Sim (pode ser nullptr)
Precisa desreferenciar ❌ Não (usa diretamente) ✅ Sim (usa *x)
Pode religar ❌ Não (uma vez vinculado, não pode mudar) ✅ Sim (pode apontar para outra variável)
Recomendação ⭐⭐⭐⭐⭐ (preferir) ⭐⭐⭐ (usar quando necessário)


4. Comparação dos Três Métodos de Passagem

▶ Exemplo 1: Trocar Duas Variáveis (Dificuldade ⭐⭐)

Método 1: Passagem por Valor (Falha)

CPP
#include <iostream>

void swapFailed(int a, int b) { // ❌ Passagem por valor: modifica cópias
 int temp = a;
 a = b;
 b = temp;
}

int main() {
 int x = 3, y = 5;
 swapFailed(x, y);
 std::cout << "x = " << x << ", y = " << y << std::endl; // x=3, y=5 (não trocados)
 return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
x = 5, y = 3

Método 2: Passagem por Ponteiro (Funciona)

CPP
#include <iostream>

void swapPointer(int* a, int* b) { // ✅ Passagem por ponteiro
 int temp = *a;
 *a = *b;
 *b = temp;
}

int main() {
 int x = 3, y = 5;
 swapPointer(&x, &y);
 std::cout << "x = " << x << ", y = " << y << std::endl; // x=5, y=3 (trocados)
 return 0;
}

Método 3: Passagem por Referência (Funciona, Recomendado)

CPP
#include <iostream>

void swapReference(int& a, int& b) { // ✅ Passagem por referência (recomendado)
 int temp = a;
 a = b;
 b = temp;
}

int main() {
 int x = 3, y = 5;
 swapReference(x, y); // Parece passagem por valor, mas é passagem por referência
 std::cout << "x = " << x << ", y = " << y << std::endl; // x=5, y=3 (trocados)
 return 0;
}


5. Quando Usar Qual Método de Passagem?

Cenário Método Recomendado Razão
Função não precisa modificar o parâmetro Passagem por valor ou passagem por referência const Seguro e claro
Função precisa modificar o parâmetro Passagem por referência Sintaxe concisa, segura
Precisa "retornar" múltiplos valores Passagem por referência A função pode modificar múltiplos parâmetros de referência
Parâmetro é um objeto grande (array, struct) Passagem por referência const Evita custo de cópia
Precisa representar "nada" (ex: busca falhou) Passagem por ponteiro Ponteiro pode ser nullptr

💡 Regra de ouro: Prefira passagem por referência, use passagem por ponteiro quando necessário, e passagem por valor para objetos pequenos.



6. Referência const

Se você não quer que a função modifique o parâmetro mas quer evitar o custo de cópia, use uma referência const.

CPP
#include <iostream>
#include <string>

void printName(const std::string& name) { // referência const: não pode modificar name
 std::cout << "Name: " << name << std::endl;
 // name = "Alice"; // ❌ Erro: não pode modificar uma referência const
}

int main() {
 std::string myName = "MOTO";
 printName(myName); // Não precisa copiar a string inteira — eficiente
 return 0;
}

💡 Ponto-chave: referência const é um dos métodos de passagem de parâmetros mais usados em C++, equilibrando segurança e eficiência.



7. Arrays como Parâmetros

Quando um array é passado como parâmetro, ele decai para um ponteiro (coberto em detalhes mais tarde).

CPP
#include <iostream>

// Array como parâmetro, precisa passar o comprimento
void printArray(int arr, int length) {
 for (int i = 0; i < length; i++) {
 std::cout << arr[i] << " ";
 }
 std::cout << std::endl;
}

int main() {
 int myArray[5] = {1, 2, 3, 4, 5};
 printArray(myArray, 5); // Passa nome do array (que é o endereço do primeiro elemento)
 return 0;
}

💡 Dica: Quando um array é passado como parâmetro, a função não sabe o comprimento do array — você precisa passar um parâmetro de comprimento adicional.



8. Prática: Múltiplos Valores de Retorno

▶ Exemplo 2: Calcular Quociente e Resto (Dificuldade ⭐⭐)

CPP
#include <iostream>

// Usa parâmetros de referência para "retornar" múltiplos valores
void divide(int a, int b, int& quotient, int& remainder) {
 quotient = a / b;
 remainder = a % b;
}

int main() {
 int a = 17, b = 5;
 int q, r;
 
 divide(a, b, q, r); // q e r serão modificados
 
 std::cout << a << " / " << b << " = " << q << " ... " << r << std::endl;
 // Saída: 17 / 5 = 3 ... 2
 
 return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
17 / 5 = 3 ... 2

▶ Exemplo 3: Parâmetros Padrão (Dificuldade ⭐)

CPP
#include <iostream>
#include <string>

// Função com parâmetros padrão
void greet(const std::string& name, const std::string& greeting = "Hello") {
    std::cout << greeting << "," << name << "!" << std::endl;
}

int main() {
    greet("Zhang San");              // Usa parâmetro padrão
    greet("Li Si", "Good morning");     // Especifica parâmetro
    greet("Wang Wu", "Good evening");     // Especifica parâmetro
    return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Hello,Zhang San!
Good morning,Li Si!
Good evening,Wang Wu!

Saída esperada:

TEXT 📖 Somente leitura
Hello,Zhang San!
Good morning,Li Si!
Good evening,Wang Wu!

❓ Perguntas Frequentes

P: Qual a diferença real entre referências e ponteiros? R: - Uma referência é um apelido para uma variável; um ponteiro é uma variável que armazena um endereço - Uma referência deve ser inicializada; um ponteiro pode ser nullptr - Uma referência não pode ser religada; um ponteiro pode - Prefira referências a menos que precise representar "nada" (então use ponteiro) P: Por que não preciso especificar o comprimento ao passar um array como parâmetro? R: Porque arrays decaem para ponteiros. void foo(int arr) é equivalente a void foo(int* arr) — arr é na verdade um ponteiro, não um array. P: Qual é mais eficiente: passagem por valor, por referência ou por ponteiro? R: - Objetos pequenos (como int): passagem por valor é mais eficiente (pequeno custo de cópia) - Objetos grandes (como arrays grandes, structs grandes): passagem por referência const é mais eficiente (evita cópia) - Quando precisa modificar um parâmetro: passagem por referência é melhor (sintaxe concisa)


P: O que é mais importante sobre parâmetros de função? R: Entenda os conceitos centrais primeiro, depois reforce-os através de exemplos práticos.

P: Como praticar parâmetros de função de forma eficiente? R: Comece com exemplos simples, aumente a dificuldade gradualmente, e sempre teste seu código.

📖 Resumo


📝 Exercícios

  1. Básico (Dificuldade ⭐): Escreva uma função void addTen(int& x) que adiciona 10 à variável passada. Teste-a em main.

  2. Intermediário (Dificuldade ⭐⭐): Escreva uma função void minMax(int arr, int length, int& min, int& max) que encontre os valores mínimo e máximo em um array (usando parâmetros de referência para "retorná-los").

  3. Desafio (Dificuldade ⭐⭐⭐): Escreva um programa que implemente "ordenar três números":

  4. Escreva uma função void sortThree(int& a, int& b, int& c) que ordene três números do menor para o maior

  5. Em main, deixe o usuário digitar três números, chame sortThree, depois exiba o resultado ordenado


9. 🚀 Próximo Passo

Agora que você aprendeu passagem de parâmetros, a seguir vamos aprender recursão (Aula 12) — a técnica incrível de uma função chamar a si mesma!

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%