Vamos supor,
int *p;
int a = 100;
p = &a;
O que o código a seguir fará realmente e como?
p++;
++p;
++*p;
++(*p);
++*(p);
*p++;
(*p)++;
*(p)++;
*++p;
*(++p);
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 p
cujo endereço é 3560200
. Agora, qual será o valor de p & a
após a execução de cada instrução?
printf
imprimirá um ponteiro com% pRespostas:
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:
ptr++; // Pointer moves to the next int position (as if it was an array) ++ptr; // Pointer moves to the next int position (as if it was an array) ++*ptr; // The value of ptr is incremented ++(*ptr); // The value of ptr is incremented ++*(ptr); // The value of ptr is incremented *ptr++; // Pointer moves to the next int position (as if it was an array). But returns the old content (*ptr)++; // The value of ptr is incremented *(ptr)++; // Pointer moves to the next int position (as if it was an array). But returns the old content *++ptr; // Pointer moves to the next int position, and then get's accessed, with your code, segfault *(++ptr); // Pointer moves to the next int position, and then get's accessed, with your code, segfault
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
fonte
verificou o programa e os resultados são como,
p++; // use it then move to next int position ++p; // move to next int and then use it ++*p; // increments the value by 1 then use it ++(*p); // increments the value by 1 then use it ++*(p); // increments the value by 1 then use it *p++; // use the value of p then moves to next position (*p)++; // use the value of p then increment the value *(p)++; // use the value of p then moves to next position *++p; // moves to the next int location then use that value *(++p); // moves to next location then use that value
fonte
A seguir está uma instanciação das várias sugestões "basta imprimir". Eu achei instrutivo.
#include "stdio.h" int main() { static int x = 5; static int *p = &x; printf("(int) p => %d\n",(int) p); printf("(int) p++ => %d\n",(int) p++); x = 5; p = &x; printf("(int) ++p => %d\n",(int) ++p); x = 5; p = &x; printf("++*p => %d\n",++*p); x = 5; p = &x; printf("++(*p) => %d\n",++(*p)); x = 5; p = &x; printf("++*(p) => %d\n",++*(p)); x = 5; p = &x; printf("*p++ => %d\n",*p++); x = 5; p = &x; printf("(*p)++ => %d\n",(*p)++); x = 5; p = &x; printf("*(p)++ => %d\n",*(p)++); x = 5; p = &x; printf("*++p => %d\n",*++p); x = 5; p = &x; printf("*(++p) => %d\n",*(++p)); return 0; }
Retorna
(int) p => 256688152 (int) p++ => 256688152 (int) ++p => 256688156 ++*p => 6 ++(*p) => 6 ++*(p) => 6 *p++ => 5 (*p)++ => 5 *(p)++ => 5 *++p => 0 *(++p) => 0
Eu lancei os endereços do ponteiro para
int
s para que eles pudessem ser facilmente comparados.Eu compilei com o GCC.
fonte
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:#include <stdio.h> int main() { int a = 100; int *p = &a; printf("%p\n",(void*)p); ++(*p++); printf("%p\n",(void*)p); printf("%d\n",a); return 0; }
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.
fonte
++*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,++*++p
funcionará bem sem parênteses também (mas incrementa o valor que é apontado após o incremento do ponteiro).Note: 1) Both ++ and * have same precedence(priority), so the associativity comes into picture. 2) in this case Associativity is from **Right-Left** important table to remember in case of pointers and arrays: operators precedence associativity 1) () , [] 1 left-right 2) * , identifier 2 right-left 3) <data type> 3 ---------- let me give an example, this might help; char **str; str = (char **)malloc(sizeof(char*)*2); // allocate mem for 2 char* str[0]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char str[1]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char strcpy(str[0],"abcd"); // assigning value strcpy(str[1],"efgh"); // assigning value while(*str) { cout<<*str<<endl; // printing the string *str++; // incrementing the address(pointer) // check above about the prcedence and associativity } free(str[0]); free(str[1]); free(str);
fonte