Como incrementar o endereço de um ponteiro e o valor do ponteiro?


98

Vamos supor,

O que o código a seguir fará realmente e como?

Eu sei, isso é meio confuso em termos de codificação, mas quero saber o que realmente vai acontecer quando codificarmos assim.

Nota: Vamos supor que o endereço de a=5120300, é armazenado no ponteiro pcujo endereço é 3560200. Agora, qual será o valor de p & aapós a execução de cada instrução?


3
por que você simplesmente não executa no depurador?
AndersK de

24
Bem ... por que não simplesmente experimentar e ver? printfimprimirá um ponteiro com% p
Brian Roach

Se você está curioso sobre comportamento, apenas brinque com ele. Basta escrever um programa em C simples que passe por todos esses casos de uso e veja se faz sentido para você.
Cyrus de

@AndersK. Talvez o OP espere um comportamento indefinido? ...Ou talvez não.
Mateen Ulhaq

Respostas:


181

Primeiro, o operador ++ tem precedência sobre o operador * e os operadores () têm precedência sobre todo o resto.

Em segundo lugar, o operador de número ++ é o mesmo que o operador de número ++ se você não estiver atribuindo a nada. A diferença é number ++ retorna number e então incrementa number, e ++ number incrementa primeiro e então retorna.

Terceiro, ao aumentar o valor de um ponteiro, você o está incrementando pelo tamanho de seu conteúdo, ou seja, você está incrementando como se estivesse iterando em um array.

Então, para resumir tudo:

Como há muitos casos aqui, posso ter cometido algum engano, corrija-me se estiver errado.

EDITAR:

Então eu estava errado, a precedência é um pouco mais complicada do que a que escrevi, veja aqui: http://en.cppreference.com/w/cpp/language/operator_precedence


6
* ptr ++, o valor não é incrementado, o ponteiro sim. Esses operadores unários têm a mesma precedência, mas são avaliados da direita para a esquerda. O código significa "pegar o conteúdo de onde ptr aponta, então incrementar ptr". É um código C muito comum (e sim, bastante confuso). Corrija isso e eu removerei o downvote. O mesmo para * (ptr) ++, o parêntese não faz nada.
Lundin

Muito obrigado Lundin, perdi mais alguma coisa?
felipemaia

@Lundin Olá, a resposta acima foi corrigida agora? Obrigado.
Unheilig

4
@Unheilig A primeira frase ainda está completamente errada, postfix ++ tem precedência sobre unário * que tem a mesma precedência que prefixo ++. Tirando isso, parece ok.
Lundin,

4
@felipemaia Tem certeza de que haverá um segfault? Talvez seja apenas um comportamento indefinido?
jotik de

15

verificou o programa e os resultados são como,


2
@alex use significa, por exemplo, considere a instrução, 'int * a = p ++;' Aqui, o primeiro valor do ponteiro 'p' será usado para e depois disso p moverá para a próxima posição. Assim, de fato, após a execução da instrução acima, 'a' terá o endereço do local anterior apontado por 'p' e 'p' estará apontando para a próxima posição. Isso é primeiro use o valor de 'p' para a expressão de atribuição como acima e, em seguida, incremente o valor de 'p' para apontar para a próxima posição
Sujith R Kumar

Resumindo, acho que ele usa a frase "usar" para o termo mais formal "atribuir". Isso é tudo.
Apekshik Panigrahi

4

A seguir está uma instanciação das várias sugestões "basta imprimir". Eu achei instrutivo.

Retorna

Eu lancei os endereços do ponteiro para ints para que eles pudessem ser facilmente comparados.

Eu compilei com o GCC.


1
Eu mudaria isso para incluir o valor de x e p após a operação.
NetJohn

3

Com relação a "Como incrementar o endereço de um ponteiro e o valor do ponteiro?" Acho que ++(*p++);está bem definido e faz o que você está pedindo, por exemplo:

Não é modificar a mesma coisa duas vezes antes de um ponto de sequência. Não acho que seja um bom estilo para a maioria dos usos - é um pouco enigmático para o meu gosto.


Na verdade, os parênteses são desnecessários: ++*p++irá incrementar com sucesso o valor e o ponteiro (o postfix é ++mais forte do que a desreferência *, e isso acontece antes do prefixo ++devido à ordem). Os parênteses são necessários apenas quando você precisa do valor antes de incrementá-lo (*p++)++. Se você usar all-prefix, ++*++pfuncionará bem sem parênteses também (mas incrementa o valor que é apontado após o incremento do ponteiro).
cmaster - restabelecer monica

1

O que é associatividade?
71GA

1
no código você pode ver o * str ++, agora aqui * e ++ têm a mesma precedência (mesma prioridade no termo do leigo) e também * str ++ não são separados usando parênteses como * (str ++) ou (* str) ++, então torna-se necessário como deve ser avaliado. então, da direita para a esquerda significa (x = str ++) e então (y = * x)
Abhishek DK
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.