ponteiro para ponteiro [RESOLVIDO]

1. ponteiro para ponteiro [RESOLVIDO]

Bruna Almeida
FennFelis

(usa Ubuntu)

Enviado em 16/11/2012 - 00:13h

Como passo ponteiro para ponteiro como referencia? e como eu passo essa referencia como referencia para outra funcao?
Na linguagem C


  


2. Re: ponteiro para ponteiro [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 16/11/2012 - 06:37h

Em C, os argumentos de funções são sempre passados por valor, com cópias dos valores originais, e isso vale inclusive para argumentos que são de um tipo "ponteiro para alguma coisa". No caso de argumentos do tipo ponteiro, cabe a você garantir que tais argumentos são efetivamente endereços de dados de um tipo compatível com o do protótipo da função.

O trabalho com referências em C se faz sempre explicitamente, por meio dos operadores & e *, que obtêm, respectivamente, o endereço de uma variável e o acesso ao dado contido num endereço. Desse modo, sendo var uma variável de um tipo qualquer (desde que não seja volatile nem array), é garantido que *&var==var, e, sendo p um ponteiro para dado válido, é verdade que &*p==p.

Um conceito interessante usado pela linguagem C é o de lvalue. Simplificadamente, um lvalue é uma expressão que pode aparecer do lado esquerdo de uma operação de atribuição, porque tal expressão resulta em algo que tem um endereço próprio na memória, que pode ser obtido com o operador & (leia mais sobre lvalue na Wikipedia, por exemplo, ou outra referência mais específica).

Se você tiver uma variável var do tipo X, o tipo de &var será "ponteiro para X". No código abaixo, isso fica claro.

int i=0;
int * p_i=&i; /* "X" é int */
int ** p_p_i=&p_i; /* "X" é (int *) */
int *** p_p_p_i=&p_p_i; /* "X" é (int **) */

i++; /* i==1 */
(*p_i)++; /* i==2 */
(**p_p_i)++; /* i==3 */
(***p_p_i)++; /* i==4 */

int a_i[2]={1, 2};
p_i=a_i; /* a_i não é lvalue, mas é sinônimo de "&a[0]"
(a[0] é lvalue) */
(*p_i)++; /* a[0]==2 */
(*p_p_i)++; /* p_i++, ou seja: p_i==&a[1] */
(*p_i)--; /* a[1]==1 */



3. Re: ponteiro para ponteiro [RESOLVIDO]

Bruna Almeida
FennFelis

(usa Ubuntu)

Enviado em 16/11/2012 - 13:12h

paulo1205 escreveu:

Em C, os argumentos de funções são sempre passados por valor, com cópias dos valores originais, e isso vale inclusive para argumentos que são de um tipo "ponteiro para alguma coisa". No caso de argumentos do tipo ponteiro, cabe a você garantir que tais argumentos são efetivamente endereços de dados de um tipo compatível com o do protótipo da função.

O trabalho com referências em C se faz sempre explicitamente, por meio dos operadores & e *, que obtêm, respectivamente, o endereço de uma variável e o acesso ao dado contido num endereço. Desse modo, sendo var uma variável de um tipo qualquer (desde que não seja volatile nem array), é garantido que *&var==var, e, sendo p um ponteiro para dado válido, é verdade que &*p==p.

Um conceito interessante usado pela linguagem C é o de lvalue. Simplificadamente, um lvalue é uma expressão que pode aparecer do lado esquerdo de uma operação de atribuição, porque tal expressão resulta em algo que tem um endereço próprio na memória, que pode ser obtido com o operador & (leia mais sobre lvalue na Wikipedia, por exemplo, ou outra referência mais específica).

Se você tiver uma variável var do tipo X, o tipo de &var será "ponteiro para X". No código abaixo, isso fica claro.

int i=0;
int * p_i=&i; /* "X" é int */
int ** p_p_i=&p_i; /* "X" é (int *) */
int *** p_p_p_i=&p_p_i; /* "X" é (int **) */

i++; /* i==1 */
(*p_i)++; /* i==2 */
(**p_p_i)++; /* i==3 */
(***p_p_i)++; /* i==4 */

int a_i[2]={1, 2};
p_i=a_i; /* a_i não é lvalue, mas é sinônimo de "&a[0]"
(a[0] é lvalue) */
(*p_i)++; /* a[0]==2 */
(*p_p_i)++; /* p_i++, ou seja: p_i==&a[1] */
(*p_i)--; /* a[1]==1 */


Eu gostaria de saber como passar um ponteiro para ponteiro por referencia
Exemplo:

int *n; //Ponteiro normal
funcao(&n); //Chamada para funcao
void funcao(int **n); //Funcao declarada

//Se fosse um ponteiro para ponteiro
//ponteiro para ponteiro eu faria assim, entao?
int **n;
funcao(&(*n)); //Chamada para funcao
void funcao(int ***n); //Funcao declarada, tentei deste modo, e só consegui alterar na funcao chamada, na original continuou com o valor que tinha antes


Em outras palavras, eu quero passar um ponteiro para ponteiro para uma funcao qualquer, nele fazer uma alteracao, e na funcao original continuar com o conteudo alterado



4. Re: ponteiro para ponteiro [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 16/11/2012 - 15:26h

Veja os exemplos que eu mostrei usando p_p_i e p_p_p_i. O que vale para atribuição vale para passagem de argumentos de função.

Sendo mais explícito ainda: o operador "&" obtém uma referência a partir de um lvalue. Só que o valor devolvido por esse operador não é lvalue, logo ele não poder ser aplicado novamente (i.e.: é _sempre_ inválido fazer algo como &(&i)). Tendo uma referência, você pode aplicar o operador "*" para ter acesso ao dado que está na memória referenciada. Então, se eu tenho um ponteiro para ponteiro para inteiro (int **) chamado p_p_i, e esse ponteiro contém um endereço válido de um ponteiro que contém um endereço válido de um valor inteiro, *p_p_i é do tipo ponteiro para inteiro e designa o ponteiro do valor inteiro, e **p_p_i, que é um sinônimo de *(*p_p_i) vai permitir chegar ao valor inteiro.

Em outras palavras, o operador "&" pode ser lido como "endereço de", e "*", como "valor contido na posição de memória designada por".

Normalmente, quando você tem uma função que precisa modificar um dado do tipo X ao longo de sua execução, ela recebe um argumento do tipo X*. Se o X no seu caso, for Y*, é claro que X* será Y**.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts