Graciano Torrão's Deblog

O meu diário de trabalho em Debian … e não só!

Funções: Passagem de parâmetros por valor/referência em C/C++

Vou partir do princípio que todos sabem um pouco de linguagem C/C++ e que compreendem a forma de criação e utilização de funções. Também vou tentar escrever o mínimo possível e passar a ideia através de quatro exemplos muito simples, sempre à volta da clássica função troca.

Função Troca: recebe dois valores a e b, e troca os respectivos conteúdos.

Passagem de parâmetros por valor: A função recebe uma cópia da variável que é fornecida quando é invocada. Todas as alterações feitas dentro da função não vão afectar os valores originais.

Passagem de parâmetros por referência: Neste caso o que é enviado para a função é uma referência às variáveis utilizadas, e não uma simples cópia, pelo que as alterações realizadas dentro da função irão certamente alterar os valores contidos nessas variáveis.

Exemplo 1 – Passagem de parâmetros por valor – Linguagem C

#include<stdio.h>
void troca(int a, int b){
        int temp;
        temp=a;
        a=b;
        b=temp;
}
int main(){
        int a=2,b=3;
        printf("Antes de chamar a função :\na=%d\nb=%d\n",a,b);
        troca(a,b);
        printf("Depois de chamar a função:\na=%d\nb=%d\n",a,b);
        return 0;
}

Apesar da troca dentro da função, os valores originais não sofreram alterações.

Exemplo 2 – Passagem de parâmetros por referência – Linguagem C

Contradizendo o título, em C só existe a passagem de parâmetros por valor (obrigatório o uso de apontadores).

#include<stdio.h>
void troca(int *a, int *b){
        int temp;
        temp=*a;
        *a=*b;
        *b=temp;
}
int main(){
        int a=2,b=3;
        printf("Antes de chamar a função :\na=%d\nb=%d\n",a,b);
        troca(&a,&b);
        printf("Depois de chamar a função:\na=%d\nb=%d\n",a,b);
        return 0;
}

A troca dentro da função reflecte-se nos valores originais.

Exemplo 3 – Passagem de parâmetros por valor – Linguagem C++

#include<iostream>
using namespace std;
void troca(int a, int b){
        int temp;
        temp=a;
        a=b;
        b=temp;
}
int main(){
        int a=2,b=3;
        cout<<"Antes de chamar a função  :\na="<<a<<"\nb="<<b<<endl;
        troca(a,b);
        cout<<"Depois de chamar a função :\na="<<a<<"\nb="<<b<<endl;
        return 0;
}

Situação semelhante à apresentada no exemplo 1.

Exemplo 4 – Passagem de parâmetros por referência – Linguagem C++

#include<iostream>
using namespace std;
void troca(int &a, int &b){
        int temp;
        temp=a;
        a=b;
        b=temp;
}
int main(){
        int a=2,b=3;
        cout<<"Antes de chamar a função  :\na="<<a<<"\nb="<<b<<endl;
        troca(a,b);
        cout<<"Depois de chamar a função :\na="<<a<<"\nb="<<b<<endl;
        return 0;
}

Como se pode verificar, a evolução da linguagem C para C++ veio simplificar algumas tarefas:)

About these ads

19 responses to “Funções: Passagem de parâmetros por valor/referência em C/C++

  1. DiH Setembro 8, 2008 às 2:58 am

    Em C não existe passagem por referência ou nao ?
    Pois em C++ ele é um alias, mas em C ele seria um ponteiro para o endereço, quer dizer se apontar para NULL antes de realizar qualquer operação daria erro se quisesse fazer algo em seguida.

  2. Graciano Torrão Setembro 8, 2008 às 10:34 am

    Na realidade não. Em C não existe.
    O que se faz geralmente é simular a passagem de parâmetros por referência, recorrendo para o efeito aos apontadores, que é na mesma passagem de parâmetros por valor (mas de um endereço).
    Acho que não estou a dizer asneiras!

  3. Graciano Torrão Setembro 8, 2008 às 7:37 pm

    Citando “Luís Damas”, página 312, “Linguagem C – 8ª Edição ( http://www.fca.pt/cgi-bin/fca_main.cgi/?op=2&isbn=972-722-156-4 )
    “Em C só existe passagem de parâmetros por valor.”
    O exemplo 2 não passa de um “truque” para superar esta limitação, pelo que admito que o título escolhido não esteja tecnicamente correcto.

  4. ana Novembro 12, 2008 às 6:05 pm

    qual a diferença por passagem por valor e por endereço??

  5. Leandro Novembro 14, 2008 às 2:15 pm

    Mas ainda não existem valores por referencias para matrizes. Se vc declarar por exemplo void leitura(float &matriz[10][10]) o compilador nao compila sua aplicacao

  6. Graciano Torrão Novembro 14, 2008 às 2:58 pm

    O nome de um array já é por si um apontador.
    Por exemplo:

    #include
    using namespace std;
    int main(){
    int x[5] = { 1, 2, 3, 4 ,5};
    cout << x[0] << endl;
    cout << *x << endl;
    cout << x[2] << endl;
    cout << *x+2 << endl;
    }

    x[0] é o mesmo que *x
    x[2] é o mesmo que *x+2

    Nas funções vai ser preciso ter isto em conta.
    Vou ver se tiro isso da matriz a limpo!

    • Lorentz Maio 6, 2009 às 11:38 pm

      Apenas uma correção:

      x[2] é o mesmo que *(x+2)

      • Graciano Torrão Maio 18, 2009 às 10:22 pm

        Boa ;)

  7. Julio Cesar Maio 12, 2009 às 4:31 am

    Na passagem de parametro por valor, o argumento passado é uma cópia da váriável original, dessa forma caso você altere a variável dentro do método, essa alteração não vai valer fora do método. Na passagem por referencia, alterações dentro do método são visiveis em quem chama a função.

    Abraços.

  8. Roberto Novakosky Maio 5, 2011 às 3:48 am

    Eu sempre usei a passagem por referência como no protótipo
    void troca(int &a, int &b);
    porque sempre usei C++ (TCPP, Visual C++, C++ Builder…)
    Recentemente tive problemas de sintaxe no gcc do SO Ubuntu, aí vi que a sintaxe tinha que ser C puro, com o gcc e precisei converter algumas funções minhas como exemplo a acima, para:
    void troca(int *a, int *b);
    Parabéns Graciano, expôs de forma clara o assunto. E quem puder usar um compilador C++ ao invés do ANSI C, recomendo, fica mais fácil.

  9. marques Agosto 30, 2011 às 12:41 pm

    A passagem de parâmetro por referência permite apenas acessar o endereço da variável.

  10. Alex Novembro 3, 2011 às 12:08 pm

    salve vleew

  11. Joao Maio 20, 2012 às 11:58 pm

    Ow… Mais que saco de explicação hein…

    Coloca exemplo prático, sem esse treco de ficar usando matemática, seja mais objetivo e simples.

    Passar parametro e simples, não complica não irmão !

  12. Pingback: Dica para passagem de parâmetros em C/C++ | noobprogramer

  13. Elizângela Gaspar Junho 19, 2013 às 4:55 am

    Ajudou-me mto. valeu! obgada. bjs…EliGaspar

  14. Wesley Setembro 6, 2013 às 11:08 pm

    Estou com dúvida em como retornar por referência e e por valor em uma mesma função. O problema que tenho pede pra eu fazer um algoritmo com uma função pra resolver um equação de 2°grau.Sendo que na função eu tenho que retornar -1 em caso de “a” ser igual a zero, retornar 1 em caso de haver uma raiz, 2 em caso de duas raizes. Além disso(eis aí o problema) tenho que retornar o valor das raízes, sendo que eles devem ser retornados por referência.

    • Graciano Torrão Setembro 7, 2013 às 10:41 am

      Uma função do tipo int nomeDaFuncao(int a, int b, int c, int &x1, int &x2) não serve?
      A função devolve o tal -1, 1 ou 2 e as raízes são devolvidas por referência!

      • Wesley Setembro 7, 2013 às 11:08 am

        Talvez eu esteja fazendo errado, estou programando em C e usei o mesmo protótipo que você sugeriu e sempre aparece uma mensagem de erro. Parece que em C não é aceitável uma função com passagem por referência e por valor juntos.

  15. Amanda Março 11, 2014 às 11:07 pm

    Muito obrigada pela explicação simples e objetiva…Foi de grande ajuda

Deixar uma resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

WordPress.com Logo

Está a comentar usando a sua conta WordPress.com Log Out / Modificar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Log Out / Modificar )

Facebook photo

Está a comentar usando a sua conta Facebook Log Out / Modificar )

Google+ photo

Está a comentar usando a sua conta Google+ Log Out / Modificar )

Connecting to %s

Seguir

Get every new post delivered to your Inbox.

Junte-se a 196 outros seguidores

%d bloggers like this: