error: lvalue required as left operand of assignment [RESOLVIDO]

1. error: lvalue required as left operand of assignment [RESOLVIDO]

Henrique Cesar
henriquecb

(usa Arch Linux)

Enviado em 16/11/2016 - 23:52h

Boa Noite
Estou fazendo a implementação de uma árvore SBB poŕem estou com um problema
A seguinte função
void dd(sbb *ptr) {
sbb *no = ptr;
sbb *dir = no->dir;
no->dir = dir->esq;
dir->esq = no;
dir->dirTipo = SBB_VERTICAL;
no->dirTipo = SBB_VERTICAL;
&ptr = dir;
}
faz o balanceamento da arvore, porém essa parte
&ptr = dir; 
da o seguinte erro
error: lvalue required as left operand of assignment
E se eu retiro o & eu tenho problemas pois a função não atualiza a raiz da árvore o que impossibilita eu fazer uma pesquisa na mesma.
Alguem pode me ajudar? Obrigado


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 17/11/2016 - 01:06h

Todos os argumentos de função no C são sempre passados por valor. Isso significa os argumentos têm seus valores calculados, e cópias desse valores calculados é que são passados à função.

Para que uma função altere o valor de uma variável declarada fora do escopo visível para essa função, a técnica usada em C é usar ponteiros como argumentos, e passar como argumentos para a função os endereços dos objetos que serão modificados. Mesmo que a função receba uma cópia do valor calculado antes de ela ser chamada, se esse valor for um endereço então cópias do endereço apontarão para o mesmo dado. Dentro da função, você aplicará o operador de acesso a conteúdo, que é o operador unário *, sobre o endereço, e você terá chegado ao dado que evntualmente poderá modificar.

Mas se o dado que você quiser modificar já for de um tipo ponteiro? Então você terá de fazer seu argumento ser um ponteiro de ponteiro, e vai ter de extrair o endereço onde a variável cujo tipo é ponteiro reside.

int i;
// - "i" é uma variável (existe um lugar na memória especificamente reservado para guardar seu valor);
// - o tipo (do valor) de "i" é int;
// - "&i" calcula o endereço onde "i" é armazenado;
// - "&i" NÃO É uma variável, mas tão somente um valor calculado;
// - logo não é possível fazer "&&i";
// - o tipo de "&i" é "ponteiro para 'int'";
// - "*&i" indica o "conteúdo do endereço de i", logo é um sinônimo de "i";
// - logo o conteúdo de uma cópia de "endereço de i" também é um sinônimo de "i".

int *pi=&i;
// - "pi" é uma variável (existe um lugar na memória especificamente reservado para guardar seu valor);
// - o tipo (do valor) de "pi" é "ponteiro para int";
// - "*pi" indica o "conteúdo do valor (que é um endereço) de pi";
// - o tipo de "*pi" é "int";
// - "&pi" calcula o endereço onde "pi" é armazenado;
// - "&pi" NÃO É uma variável, mas tão somente um valor calculado;
// - logo não é possível fazer "&&pi";
// - o tipo de "&pi" é "ponteiro para 'ponteiro para `int´'";
// - "*&pi" indica o "conteúdo do endereço de pi", logo é um sinônimo de "pi";
// - logo o conteúdo de uma cópia de "endereço de pi" também é um sinônimo de "pi";
// - "**&pi" indica o "conteúdo do conteúdo do endereço de pi", logo é um sinônimo do "*pi";
// - logo o conteúdo do conteúdo de uma cópia de "endereço de pi" também é um sinônimo de "*pi".


Essa introdução toda é para ajudar a entender que você vai ter de fazer a função ter um parâmetro que é um "ponteiro para ponteiro para sbb". Dentro dela, você terá de usar o operador de obtenção de conteúdo para chegar ao dado do tipo "ponteiro para sbb" (tanto para consultá-lo quanto para modificá-lo), e se quiser chegar ao dado do tipo "sbb" terá de aplicar o operador de conteúdo uma segunda vez.

void dd(sbb **ptr) {
sbb *no = *ptr;
sbb *dir = no->dir;
no->dir = dir->esq;
dir->esq = no;
dir->dirTipo = SBB_VERTICAL;
no->dirTipo = SBB_VERTICAL;
*ptr = dir;
}


E, para chamar essa função, eis como você poderia fazer.

sbb *p_sbb;

/* Cria algum conteúdo e faz com que o ponteiro p_sbb aponte para ele. */

dd(&p_sbb);
/* Aqui o valor de p_sbb terá sido modificado, de acordo com a lógica da função. */


3. Re: error: lvalue required as left operand of assignment [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 17/11/2016 - 00:03h

&ptr = dir; 


& serve para pegar o endereço de memória da variável.
Você tem ideia de o que você quis dizer com o código?

* serve para retornar o valor de um endereço de memória.
Será que não é o caso de trocar a posição das notações?

----------------------------------------------------------------------------------------------------------------
Nem direita, nem esquerda. Quando se trata de corrupção o Brasil é ambidestro.
(anônimo)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden



4. Re: error: lvalue required as left operand of assignment [RESOLVIDO]

Henrique Cesar
henriquecb

(usa Arch Linux)

Enviado em 17/11/2016 - 00:47h

listeiro_037 escreveu:

&ptr = dir; 


& serve para pegar o endereço de memória da variável.
Você tem ideia de o que você quis dizer com o código?

* serve para retornar o valor de um endereço de memória.
Será que não é o caso de trocar a posição das notações?

----------------------------------------------------------------------------------------------------------------
Nem direita, nem esquerda. Quando se trata de corrupção o Brasil é ambidestro.
(anônimo)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden

Basicamente, o que essa função faz é trocar a posição de 3 ponteiros, ou seja
suponha que eu tenha 2->3->4, a função vai transformar em 2<-3->4
Porém, eu preciso que a raiz (que está na main) seja atualizada para o 3 (já que a função mudou), mas ela continua sendo o 2.
O meu professor postou esse codigo e nele, ele usa esse operador &. Por isso o coloquei.



5. Re: error: lvalue required as left operand of assignment [RESOLVIDO]

Henrique Cesar
henriquecb

(usa Arch Linux)

Enviado em 17/11/2016 - 01:19h

paulo1205 escreveu:

Todos os argumentos de função no C são sempre passados por valor. Isso significa os argumentos têm seus valores calculados, e cópias desse valores calculados é que são passados à função.

Para que uma função altere o valor de uma variável declarada fora do escopo visível para essa função, a técnica usada em C é usar ponteiros como argumentos, e passar como argumentos para a função os endereços dos objetos que serão modificados. Mesmo que a função receba uma cópia do valor calculado antes de ela ser chamada, se esse valor for um endereço então cópias do endereço apontarão para o mesmo dado. Dentro da função, você aplicará o operador de acesso a conteúdo, que é o operador unário *, sobre o endereço, e você terá chegado ao dado que evntualmente poderá modificar.

Mas se o dado que você quiser modificar já for de um tipo ponteiro? Então você terá de fazer seu argumento ser um ponteiro de ponteiro, e vai ter de extrair o endereço onde a variável cujo tipo é ponteiro reside.

int i;
// - "i" é uma variável (existe um lugar na memória especificamente reservado para guardar seu valor);
// - o tipo (do valor) de "i" é int;
// - "&i" calcula o endereço onde "i" é armazenado;
// - "&i" NÃO É uma variável, mas tão somente um valor calculado;
// - logo não é possível fazer "&&i";
// - o tipo de "&i" é "ponteiro para 'int'";
// - "*&i" indica o "conteúdo do endereço de i", logo é um sinônimo de "i";
// - logo o conteúdo de uma cópia de "endereço de i" também é um sinônimo de "i".

int *pi=&i;
// - "pi" é uma variável (existe um lugar na memória especificamente reservado para guardar seu valor);
// - o tipo (do valor) de "pi" é "ponteiro para int";
// - "*pi" indica o "conteúdo do valor (que é um endereço) de pi";
// - o tipo de "*pi" é "int";
// - "&pi" calcula o endereço onde "pi" é armazenado;
// - "&pi" NÃO É uma variável, mas tão somente um valor calculado;
// - logo não é possível fazer "&&pi";
// - o tipo de "&pi" é "ponteiro para 'ponteiro para `int´'";
// - "*&pi" indica o "conteúdo do endereço de pi", logo é um sinônimo de "pi";
// - logo o conteúdo de uma cópia de "endereço de pi" também é um sinônimo de "pi";
// - "**&pi" indica o "conteúdo do conteúdo do endereço de pi", logo é um sinônimo do "*pi";
// - logo o conteúdo do conteúdo de uma cópia de "endereço de pi" também é um sinônimo de "*pi".


Essa introdução toda é para ajudar a entender que você vai ter de fazer a função ter um parâmetro que é um "ponteiro para ponteiro para sbb". Dentro dela, você terá de usar o operador de obtenção de conteúdo para chegar ao dado do tipo "ponteiro para sbb" (tanto para consultá-lo quanto para modificá-lo), e se quiser chegar ao dado do tipo "sbb" terá de aplicar o operador de conteúdo uma segunda vez.

void dd(sbb **ptr) {
sbb *no = *ptr;
sbb *dir = no->dir;
no->dir = dir->esq;
dir->esq = no;
dir->dirTipo = SBB_VERTICAL;
no->dirTipo = SBB_VERTICAL;
*ptr = dir;
}


E, para chamar essa função, eis como você poderia fazer.

sbb *p_sbb;

/* Cria algum conteúdo e faz com que o ponteiro p_sbb aponte para ele. */

dd(&p_sbb);
/* Aqui o valor de p_sbb terá sido modificado, de acordo com a lógica da função. */

Colega, muito obrigado mesmo
Você não tem noção do quanto isso me esclareceu e me ajudou.







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts