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. */