Jump to content

passagem de ponteiros de referencia


Recommended Posts

Posted (edited)

Prentendo fazer uma funcao que receba um ponteiro para uma lista e este tem que ser passado por referência como posso fazer?

Assim int pont(lista * base)

ou assim int pont(lista ** base) ?

P.S. Neste enumerado qual é o erro?

enum operacao {\, *, +, -};
Edited by einstein
Posted

existe o conceito de passagem por referência, no entanto tens que perceber que em C a passagem de valores para uma função é sempre por valor

o teu caso será passar uma referência (e não passagem por referência, o português é parecido mas é diferente)

um ponteiro pode ser considerado como uma referência. testa estes exemplos para perceberes:

void func1(int * i) {
 *i = 20; // estás a alterar o valor na posição de memória apontado por i;
 i = 20; // estás a alterar o valor do ponteiro i (esta variável é local à função)
}
void func2(int ** i) {
 **i = 30; // estás a alterar o valor posição de memória apontado por *i;
 *i = 30; // estás a alterar o valor do ponteiro i (esta variável é do main)
 i = 30; // estás a alterar o valor do ponteiro i (esta variável é local à função)
}
int main(void) {
 int i = 10;
 int * p = &i;

 // i = 10
 // p = 0x4ffffff (valor de exemplo da posição de memória da variável i)
 printf("%p >> %d\n", p, i);

 func1(p);

 // i = 20;
 // p = 0x4ffffff (o valor de p não foi alterado)
 printf("%p >> %d\n", p, i);


 func1(&p);


 // i = 30;
 // p = 30 (o valor de p foi alterado)
 printf("%p >> %d\n", p, i);

 return 0;
}

no que toca à tua enumeração

tens operadores, porventura deverás queres carateres deste género

enum operacao {'\', '*', '+', '-'};
  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Posted

Prentendo fazer uma funcao que receba um ponteiro para uma lista e este tem que ser passado por referência como posso fazer?

Ao passar um ponteiro para algo já estás a passar uma referência para esse algo. A única diferença para as referências em C++ é que nessas não é necessário usar nenhum operador para passar o parâmetro; o compilador cria o ponteiro nos bastidores.

Podes passar parâmetros de duas maneiras: por valor, em que crias uma cópia do mesmo e é essa cópia que é passada à função, ou por ponteiro/referência, em que passas um ponteiro para o valor. A diferença funcional entre as duas é que a passagem por valor não permite alterar o parâmetro original, apesar de permitir alterar a cópia, enquanto que qualquer alteração num valor passado por ponteiro é feita no próprio valor, permitindo passar mais de um valor de retorno da função. Portanto :

int pont(lista * base)

P.S. Neste enumerado qual é o erro?

Os símbolos que usas na enumeração são símbolos reservados em C/C++. Podes fazer :

enum operacao {divisao, multiplicacao, soma, divisao};
  • Vote 1
Posted (edited)

Muito obrigado aos dois pela explicação já percebi . Só que ao fazer uma função com este raciocio mas esta funcao retire um valor da minha lista e o armazene numa variavel e em seguida elimine essa estrutura ao chamar esta função duas vezes o meu programa rebenta.

float real_op(pilha * base1){
 float val=0.0;
 pilha * aux;
 val=base1->a;
 aux=base1;
 base1=aux->seg;
 free(aux);
return val;
}
Edited by einstein
Posted

mete código de validação:

float real_op(pilha * base1){
 float val=0.0;
 pilha * aux;

 if (base1 == NULL) {
   return 0.0; // pilha vazia ??
 }

 val=base1->a;

 aux=base1;
 base1=aux->seg;
 free(aux);

 return val;
}

se continuas a ter problemas então tens de verificar o código de inserção na pilha

IRC : sim, é algo que ainda existe >> #p@p
Posted

Não me expliquei bem, pois esse teu código não faz o que pensas. O parâmetro 'base1' é um ponteiro/referência para um objecto do tipo 'lista', o que permite alterar o objecto dentro da função mas não o ponteiro/referência em si. Quando escreves 'base1=aux->seg' estás a alterar o ponteiro apenas dentro da função, o que faz com que tentes fazer 'free' do mesmo bloco sempre, pois o parâmetro 'base1' será sempre o mesmo.

Relendo a tua pergunta original parece-me que o que querias era passar uma referência para um ponteiro para uma lista. Podendo-se considerar que uma referência é um ponteiro o que precisas é de passar um ponteiro para o ponteiro, ou seja 'float real_op(pilha ** base1){'. Obviamente tens de levar em consideração este nível adicional de redirecionamento no teu código.

Posted

Não me expliquei bem, pois esse teu código não faz o que pensas. O parâmetro 'base1' é um ponteiro/referência para um objecto do tipo 'lista', o que permite alterar o objecto dentro da função mas não o ponteiro/referência em si. Quando escreves 'base1=aux->seg' estás a alterar o ponteiro apenas dentro da função, o que faz com que tentes fazer 'free' do mesmo bloco sempre, pois o parâmetro 'base1' será sempre o mesmo.

Relendo a tua pergunta original parece-me que o que querias era passar uma referência para um ponteiro para uma lista. Podendo-se considerar que uma referência é um ponteiro o que precisas é de passar um ponteiro para o ponteiro, ou seja 'float real_op(pilha ** base1){'. Obviamente tens de levar em consideração este nível adicional de redirecionamento no teu código.

ah ok. Entao o código ficaria?

float real_op(pilha * base1){
 float val=0.0;
 pilha * aux;
 val=(**base1).a;
 aux=base1;
 base1=aux->seg;
 free(aux);
return val;
Posted (edited)

Não. Presumo que a tua ideia seja passar o ponteiro para o topo da pilha, implementada com uma lista ligada, e actualizá-lo ao tirar o elemento da pilha, destruindo também o elemento. Tipo :

pilha * topo_da_pilha;

mete_elemento(&topo_da_pilha, valor);  /* Mete na pilha um elemento */
mete_elemento(&topo_da_pilha, valor);
...
valor = real_op(&topo_da_pilha);   /* Tira da pilha um elemento */
valor = real_op(&topo_da_pilha);

Sendo isso podes fazer :

float real_op(pilha ** base1){
 float val=0.0;
 pilha * aux;

 val=(*base1)->a;
 aux=*base1;
 *base1=aux->seg;
 free(aux);
return val;
Edited by bsccara
  • Vote 1
Posted

Não. Presumo que a tua ideia seja passar o ponteiro para o topo da pilha, implementada com uma lista ligada, e actualizá-lo ao tirar o elemento da pilha, destruindo também o elemento. Tipo :

pilha * topo_da_pilha;

mete_elemento(&topo_da_pilha, valor);  /* Mete na pilha um elemento */
mete_elemento(&topo_da_pilha, valor);
...
valor = real_op(&topo_da_pilha);   /* Tira da pilha um elemento */
valor = real_op(&topo_da_pilha);

Sendo isso podes fazer :

float real_op(pilha ** base1){
 float val=0.0;
 pilha * aux;

 val=(*base1)->a;
 aux=*base1;
 *base1=aux->seg;
 free(aux);
return val;

Exatamente era mesmo essa a ideia já fiquei a perceber.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.