Funções e procedimentos do C++ com passagem de parâmetros por valor e referência

Desenvolvimento 16 de Novembro de 2019 às 17:17

De forma simples e resumida, é possível definir "funções"  como trechos de códigos a serem executados quando chamados. São utilizadas para realizar diversas operações ou somente para exibir algum conteúdo. Na prática tudo em C++ é uma função, até a própria int main(void) é uma função.

Porém há uma pequena diferença de função e procedimento em linguagens de programação. Funções sempre irão retornar resultados, sejam dos tipos escalares (inteiro, decimal, booleana ou texto), referências de ponteiros, objetos ou até mesmo funções. Porém os chamados procedimentos agem de forma diferente, pois estes nunca irão retornar nenhum valor. De forma geral são usados simplesmente para executar determinada rotina, sem necessidade de retornar um valor.

Os exemplos abaixo foram compilados usando o Dev-C++.

Exemplo de uma função
#include <iostream>

// Função para multiplicar
// Recebe dois inteiros (X,Y) e retorna um inteiro (X*Y)
int multiplicar(int X, int Y)
{
    return X*Y;
}

int main(int argc, char** argv) 
{
    std::cout << multiplicar(5,3); // Multiplica 5 x 3 e imprime o resultado
    std::cin.get(); // Pausa a execução do programa até o usuário pressionar uma tecla
    return 0;
}
Exemplo de um procedimento
#include <iostream>

// procedimento para multiplicar
// Recebe dois inteiros (X,Y) e mostra o resultado
// Não retorna nenhum valor
void multiplicar(int X, int Y)
{
    std::cout << (X*Y); 
}

int main(int argc, char** argv) 
{
    multiplicar(5,3); // Multiplica 5 x 3 e imprime o resultado
    std::cin.get();
    return 0;
}

Note que ambos os códigos terão o mesmo resultado, porém quando se precisar obter um valor e utiliza-lo posteriormente para outro processamento, não é possível obter o mesmo resultado com um procedimento.

#include <iostream>

// Função para multiplicar
// Recebe dois inteiros (X,Y) e retorna um inteiro (X*Y)
int multiplicar(int X, int Y)
{
    return X*Y;
}

int main(int argc, char** argv) 
{
    int resultado = multiplicar(5,3); // Multiplica 5 x 3 e armazena o resultado
    int final = multiplicar(resultado,2); // Multiplica o resultado anterior * 2
    std::cout << final; // Imprime o resultado final
    std::cin.get(); // Pausa a execução do programa até o usuário pressionar uma tecla
    return 0;
}

O uso de funções e procedimentos é altamente recomendável quando for necessário, pois incentiva o uso de boas práticas de programação, que fazem partes da engenharia de software, evitando a repetição de código e mantendo uma melhor legibilidade de seu código.

Passagem de parâmetro por valor e referência

Há dois meios de realizar a passagem de parâmetro em linguagens de programação como o C++, sendo a passagem por valor e referência. Veja os exemplos.

Passagem de parâmetro por valor
#include <iostream>

int multiplicar(int X, int Y)
{
    // Modifica o X para 2
    X = 2;
    return X*Y;
}

int main(int argc, char** argv) 
{
    int valor = 3;
    int resultado = multiplicar(valor, 3);
    std::cout << valor; // SAÍDA: 3
}
Passagem de parâmetro por referência
#include <iostream>

int multiplicar(int &X, int Y)
{
    // Modifica o X para 2
    X = 2;
    return X*Y;
}

int main(int argc, char** argv) 
{
    int valor = 3;
    int resultado = multiplicar(valor, 3);
    std::cout << valor; // SAÍDA: 2
}

Note que em ambos códigos o valor de X foi modificado para 2, porém apenas na passagem por referência (incluindo um & antes do X na função multiplicar) a variável sofreu alterações.

Isto ocorre porque na passagem de parâmetros por valor, o valor da variável é copiado para a função, então seu valor original não sofre modificações caso seja alterado dentro da função. No caso da passagem por referência, a variável não é copiada e sim referenciada através de um ponteiro, caso esta sofra alterações dentro da função, seu valor original também será alterado.

Quando utilizar

Utilize funções sempre que possível e necessário. Para a passagem de parâmetro, na maior parte das vezes a passagem por valor será mais que o suficiente, enquanto que a passagem por referência será utilizada somente em casos específicos onde é necessário ajustar e retornar o valor de entrada e mais algum resultado daquela função.