[RESOLVIDO] ponteiros em c

8 respostas
AntonioDiego

unsigned char *a;

alguem pode me explicar o que acontece nessa linha de codigo

*a++;

8 Respostas

ViniGodoy

Essa é realmente uma linha de código confusa. Você deve primeiro olhar a tabela de precedência de operadores:
http://en.cppreference.com/w/cpp/language/operator_precedence

E então entender que o ++ será avaliado sobre o ponteiro, e não sobre o valor. O ++ vindo no final ainda tem um detalhe sacana. Pela precedência, primeiro seria feito ++ sobre o endereo do ponteiro. Depois, você leria o valor sobre o ponteiro modificado. Porém, como estamos falando de um ++ que vem depois da expressão, isso acaba trocado:

Portanto, essa linha faz 2 coisas:
a) Ela obtém o valor na posição a (*a), sem que (*a) seja incrementado;
b) Ela adiciona o tamanho de um unsigned char ao valor do ponteiro, literalmente indo para o próximo unsigned char na memória.

Um exemplo clássico do uso desse conceito é a implementação da função strcpy:

char *strcpy(char *dest, const char *src) { char *save = dest; while(*dest++ = *src++); return save; }

Embora isso seja uma implementação comum, isso aí num sistema comercial é considerado código porco. Evite códigos que exijam profundo conhecimento de precedência de operadores, até porque, é fácil você se confundir e cair numa situação de undefined behavior (tal como x = x++).

O C já é suficientemente complicado por si só, não precisa piorar as coisas. :wink:

AntonioDiego

bem confuso mesmo.
nao entendi nada nesse codigo.
valeu.

PS:
que parametro o while ta recebendo ?ou melhor o que ta acontecendo nesse codigo ?

ViniGodoy

Acontece a mesma coisa que comentei. Você tem duas áreas de memória, de mesmo tamanho.

A src, contendo os caracteres:

E a dst, contendo qualquer porcaria:

A idéia da função é copiar o src em cima do dst. Então, você recebe um ponteiro para a primeira posição de src e para a primeira posição de dst.

O while

faz o seguinte:

  1. Atribui o valor do que está no ponteiro src sobre o valor para onde dst aponta, ou seja, roda primeiro:

Como no primeiro passo do while o valor do char onde o ponteiro de src aponta é “A”, a String dst fica assim:

  1. Em seguida, soma 1 ao ponteiro dst, fazendo-o apontar para o índice1 (que contém o valor s). E soma 1 ao valor do ponteiro src, fazendo-o apontar para a posição 1 (que contém o " ").

  2. Retorna o valor atribuído. Nesse caso o valor ‘A’. O C, como convenção, encara 0 como false, e qualquer valor diferente de 0 como true. Portanto ‘A’ é encarado como true, o que faz com que o while continue.

  3. Volta para o passo 1.

Fazendo mais uma iteração:

  1. Atribui o valor do que está no ponteiro src sobre o valor para onde dst aponta. Como no segundo passo do while o valor agora é " ", a String dst fica assim:
  1. Em seguida, soma 1 ao ponteiro dst, fazendo-o apontar para o índice 2 (que contém o valor d). E soma 1 ao valor do ponteiro src, fazendo-o apontar para o índice 2 (que contém o “v”).

  2. Retorna o valor atribuído. Nesse caso o valor ’ '. O C, como convenção, encara 0 como false, e qualquer valor diferente de 0 como true. Portanto ’ ’ é encarado como true, o que faz com que o while continue.

  3. Volta para o passo 1.

Observe que assim, src está sendo copiado para dst. Quando o while termina? Lembre-se que em C, todas as Strings são terminadas pelo caracter \0. O \0 nada mais é do que o valor 0. E quando a cópia do zero for feita, ele será retornado. 0 é false, o que faz com que o código saia do while.

Ao final, a String dst terá uma cópia exata de src.

AntonioDiego

entendi perfeitamente.
obrigado.

AntonioDiego

o guj poderia ter um opção de excuir a mensagem ou cancelar o envio.
falando nisso acabei de descobrir uma funcionalidade que não conhecia.
Click Duplo na mensagem para editar.
Quanto tempo perdido.

AntonioDiego

pra encerrar:

unsigned char *a=‘s’; // um ponteiro pode ser inicializado assim?
unsigned char b=*a++;// b sera ‘s’ e *a ira apontar para o proximo char na memoria.

ViniGodoy

O ideal nesse caso é nem usar ponteiros. Se quiser usar, você deve passar o ponteiro do char s, e não o valor.

O correto é sem o ponteiro. O * antes de uma variável que é um ponteiro significa que você quer o valor para o qual o ponteiro aponta, não o ponteiro em si. E para deixar o código menos ambíguo, é melhor:

Cuidado que o operador de ++ e – alteram também o valor dos operandos sobre o qual atuam. Ou seja, o valor de A também muda.

AntonioDiego

ok.

Criado 9 de outubro de 2011
Ultima resposta 9 de out. de 2011
Respostas 8
Participantes 2