Ainda Dúvida boba de variável ponteiro que não consigo compreender [RESOLVIDO]

1. Ainda Dúvida boba de variável ponteiro que não consigo compreender [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 01/03/2019 - 14:03h

O Exemplo abaixo, eu também estou estudando para entender, mas não estou conseguindo entender nada!
Usando o Eclipse para ver o valor da variável em tempo de execução, as informações que recebo são completamente ESTRANHAS para eu entender seu funcionamento.

DÚVIDA 1: Será que o Eclipse é a ferramenta certa para isso? OU estou lendo os valores das variáveis de forma errada?

DÚVIDA 2: Eu queria compreender como funciona esse código abaixo. Lembrando que já entendi como funciona e o que ele faz, MAS NÃO ENTENDI os valores dessas variáveis ponteiros no Eclipse!
#include <stdio.h>
void concatenate_string(char*, char*);

int main(void){
char Texto1[25] = "Nick", Texto2[] = " Aprendiz de C";

concatenate_string(Texto1, Texto2);
printf("Strings Juntas: %s\n", Texto1);
}

void concatenate_string(char *Texto1, char *Texto2){

/* NÃO ENTENDI, acompanhando o valor de Texto1 pelo Eclipse, ele parece apagar a String
MAS na verdade ele está indo para o último valor
Porém, como ele vai para o último valor, se o Valor da variável no Eclipse parece ter sido apagada completamente? */
while(*Texto1)
Texto1++; // Ele PARA esse Loop qdo o Valor é vazio! MAS SEI que de verdade não é, já que ele consegue fazer o trabalho. Mas COMO ISSO FUNCIONA?

while(*Texto2){
*Texto1 = *Texto2; // Estranhamento aqui, Texto1 recebeu vazio! Como ele mantem o valor original?
Texto2++; // Aqui ele apaga e vai para o próximo caracter
Texto1++; // Ele faz o mesmo aqui, apagando o que escreveu anteriormente. Mas não apaga de verdade, já que o programa funciona!
}
*Texto1 = '\0';
}



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 01/03/2019 - 20:15h

Agora entendi.

Repare na linha que diz "Texto1++;". Perceba que o que ela faz é deslocar o ponteiro para o próximo caráter. Nada está sendo apagado: você é que está mudando o referencial a partir de onde está observando (repare no endereço hexadecimal que aparece antes do texto, e veja como ele vai aumentando de um em um).

Como esse ponteiro é uma cópia interna à função do endereço do primeiro elemento do array original, não tem problema nenhum você alterar esse endereço copiado, pois nenhum conteúdo será perdido, No entanto, se você quiser permanecer observando o array sempre a partir do seu endereço inicial original, não vai poder fazê-lo usando um ponteiro que vai sendo alterado a cada iteração. Você teria de usar uma variável adicional para tanto.

... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)

3. Re: Ainda Dúvida boba de variável ponteiro que não consigo compreender

Paulo
paulo1205

(usa Ubuntu)

Enviado em 01/03/2019 - 18:12h

Nick-us escreveu:

O Exemplo abaixo, eu também estou estudando para entender, mas não estou conseguindo entender nada!
Usando o Eclipse para ver o valor da variável em tempo de execução, as informações que recebo são completamente ESTRANHAS para eu entender seu funcionamento.

DÚVIDA 1: Será que o Eclipse é a ferramenta certa para isso? OU estou lendo os valores das variáveis de forma errada?


Nunca usei Eclipse (ou, se usei, faz muitos anos, para tentar mexer com Java), então não sei quão bom ele é.

DÚVIDA 2: Eu queria compreender como funciona esse código abaixo. Lembrando que já entendi como funciona e o que ele faz, MAS NÃO ENTENDI os valores dessas variáveis ponteiros no Eclipse!
#include <stdio.h>
void concatenate_string(char*, char*);

int main(void){
char Texto1[25] = "Nick", Texto2[] = " Aprendiz de C";

concatenate_string(Texto1, Texto2);
printf("Strings Juntas: %s\n", Texto1);
}

void concatenate_string(char *Texto1, char *Texto2){

/* NÃO ENTENDI, acompanhando o valor de Texto1 pelo Eclipse, ele parece apagar a String
MAS na verdade ele está indo para o último valor
Porém, como ele vai para o último valor, se o Valor da variável no Eclipse parece ter sido apagada completamente? */


Eu também fiquei sem entender. “Parece apagar a string” de que maneira?

Uma especulação é a seguinte: apesar de não conhecer o Eclipse e o debugger que ele usa, pode ser que você esteja sendo prejudicado por usar os mesmos nomes de símbolos em duas funções diferentes. Se você pede para acompanhar os valores de Texto1 e Texto2 no escopo de main, pode ser que o depurador os perca na hora em que ele entrar na execução de concatenate, pois o escopo muda. Talvez, dentro desse novo contexto, você tenha de pedir novamente para imprimir os mesmos nomes, e aí o depurador vai enxergar os nomes que estão no escopo dessa função.

   while(*Texto1)
Texto1++; // Ele PARA esse Loop qdo o Valor é vazio! MAS SEI que de verdade não é, já que ele consegue fazer o trabalho. Mas COMO ISSO FUNCIONA?


O que acontece é exatamente parar o laço de repetição quando se atinge o primeiro byte nulo, o que, no seu caso, vai ocorrer após se completar a quarta iteração (no quinto teste da condição do while).


while(*Texto2){
*Texto1 = *Texto2; // Estranhamento aqui, Texto1 recebeu vazio! Como ele mantem o valor original?


Onde recebeu vazio? Não vejo isso em lugar nenhum.

      Texto2++; // Aqui ele apaga e vai para o próximo caracter
Texto1++; // Ele faz o mesmo aqui, apagando o que escreveu anteriormente. Mas não apaga de verdade, já que o programa funciona!
}
*Texto1 = '\0';
}


Não sei se consegui entender corretamente suas dúvidas.

Lembre-se do seguinte:

  • Quando você usa o nome de um array numa expressão, o valor produzido e passado à expressão é um ponteiro constante para seu primeiro elemento (sendo um array de caracteres, o tipo desse valor será char *const). A isso se chama decaimento do array para ponteiro, e há apenas três exceções para essa regra: no momento da declaração do array e em expressões em que o nome do array é passado como operando dos operadores & (obtenção de endereço, que produz um ponteiro para o array inteiro, em lugar de um ponteiro para seu primeiro elemento) ou sizeof (de cálculo da memória ocupada, quando o valor produzido corresponde a todos os bytes ocupados pelo conjunto de todos os elementos do array, mais eventuais bytes usados como padding).

  • O C sempre passa argumentos para funções por cópia de valor. Assim, quando você chama “concatenate(Texto1,Texto2)”, o compilador gera código que obtém dois valores de ponteiros para os primeiros elementos de cada array e _copia_ tais valores para a função, de modo que os valores dos parâmetros, dentro da função, serão esses valores opiados. Como cópia de endereço obviamente aponta para o mesmo dado, você consegue chegar aos dados originais de cada um dos arrays. (Essa, aliás, é uma das razões por que ponteiros são tão usados em C: a única forma de fazer com que uma função tenha acesso a objetos declarados em outros escopos é passando cópias dos endereços desses objetos para essa função; se se tentasse passar os objetos diretamentes, a função receberia cópias desses objetos, de modo que qualquer alteração feita sobre as cópias seria perdida quando a função retornasse.)


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


4. Re: Ainda Dúvida boba de variável ponteiro que não consigo compreender [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 01/03/2019 - 19:34h

paulo1205 escreveu: Eu também fiquei sem entender. “Parece apagar a string” de que maneira?

O mesmo acontece com o Debug do gcc (gdb) Se estou falando corretamente.
Vou explicar: Eu compilo o programa assim gcc -g test.c
E rodo ele pelo debug: gdb ./a.out

Olhe abaixo o comportamento do GDB, pois é o mesmo que o eclipse informa.
Repare acima, que eu PARO na Linha 17 logo no início do 1º While. Ele já me Informa o valor das variáveis. Elas estão CORRETAS e completas!
Então eu continuo para a próxima linha.
Breakpoint 1, concatenate_string (Texto1=0x7fffffffdf10 "Nick", 
Texto2=0x7fffffffdf01 " Aprendiz de C") at Test5.c:17
17 while(*Texto1)

Repare que ao pedir o Valor de Texto1 ele exibe o valor COMPLETO. O que é o esperado!
(gdb) n
18 Texto1++; // Ele PARA esse Loop qdo o Valor é vazio! MAS SEI que de verdade não é, já que ele consegue fazer o trabalho. Mas COMO ISSO FUNCIONA?
(gdb) p Texto1
$1 = 0x7fffffffdf10 "Nick"

Então eu continuo... Agora, executando linha a linha, pedindo para saber o Valor da variável Texto1, ela vai perdendo as palavras uma a uma conforme o programa é excecutado. É justamente isso que eu não entendi! Porque embora o DEBUG informa que ela perde o valor. OBVIAMENTE isso de verdade não acontece, do contrário o programa não funcionaria.
(gdb) n
17 while(*Texto1)
(gdb) p Texto1
$2 = 0x7fffffffdf11 "ick"
(gdb) n
18 Texto1++;
(gdb) p Texto1
$3 = 0x7fffffffdf11 "ick"
(gdb) n
17 while(*Texto1)
(gdb) p Texto1
$4 = 0x7fffffffdf12 "ck"
(gdb)

Eu queria entender o que acontece nesse processo! O Ponteiro está usando tipo, algo temporário? Porque o valor de Text1 some?
Se vc olhar acima, Texto1 seu verdadeiro valor é Nick
Mas conforme é executado, passa para ick
Depois para ck
Depois para k
até desaparecer completamente (Vazio), é quando ele vai para o outro while... PORÉM de verdade o que parece SUMIR sem explicação, no fundo é como se a posição fosse movida, pq de verdade é como se ele estivesse lendo apenas aquela posição que SIM estaria vazia pois é o FIM do texto, para receber o novo texto.

O que me deixa confuso, é esse método, porque pensei que valores seriam exibidos sempre que eles sejam verificados.



5. Re: Ainda Dúvida boba de variável ponteiro que não consigo compreender [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 01/03/2019 - 21:01h

paulo1205 escreveu:
Repare na linha que diz "Texto1++;". Perceba que o que ela faz é deslocar o ponteiro para o próximo caráter. Nada está sendo apagado: você é que está mudando o referencial a partir de onde está observando (repare no endereço hexadecimal que aparece antes do texto, e veja como ele vai aumentando de um em um).

Eu pensei em algo assim, mas claro que eu precisava ter certeza. Obrigado!








Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts