Supongamos,
int *p;
int a = 100;
p = &a;
¿Qué hará realmente el siguiente código y cómo?
p++;
++p;
++*p;
++(*p);
++*(p);
*p++;
(*p)++;
*(p)++;
*++p;
*(++p);
Lo sé, esto es un poco complicado en términos de codificación, pero quiero saber qué sucederá realmente cuando codifiquemos así.
Nota: Supongamos que la dirección de a=5120300
se almacena en el puntero p
cuya dirección es 3560200
. Ahora bien, ¿cuál será el valor de p & a
después de la ejecución de cada declaración?
printf
imprimirá un puntero con% pRespuestas:
Primero, el operador ++ tiene prioridad sobre el operador *, y los operadores () tienen prioridad sobre todo lo demás.
En segundo lugar, el operador de número ++ es el mismo que el operador de número ++ si no los está asignando a nada. La diferencia es número ++ devuelve número y luego incrementa número, y ++ número incrementa primero y luego lo devuelve.
En tercer lugar, al incrementar el valor de un puntero, lo incrementa según el tamaño de su contenido, es decir, lo incrementa como si estuviera iterando en una matriz.
Entonces, para resumirlo todo:
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 hay muchos casos aquí, es posible que haya cometido algún error, corríjame si me equivoco.
EDITAR:
Entonces me equivoqué, la precedencia es un poco más complicada de lo que escribí, véalo aquí: http://en.cppreference.com/w/cpp/language/operator_precedence
fuente
comprobado el programa y los resultados son 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
fuente
La siguiente es una instanciación de las diversas sugerencias de "solo imprímalo". Lo encontré instructivo.
#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; }
Vuelve
(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
Lanzo las direcciones de puntero a
int
s para que puedan compararse fácilmente.Lo compilé con GCC.
fuente
Con respecto a "¿Cómo incrementar la dirección y el valor de un puntero?" Creo que en
++(*p++);
realidad está bien definido y hace lo que está pidiendo, por ejemplo:#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; }
No es modificar lo mismo dos veces antes de un punto de secuencia. Sin embargo, no creo que sea de buen estilo para la mayoría de los usos, es un poco demasiado críptico para mi gusto.
fuente
++*p++
incrementará con éxito tanto el valor como el puntero (el sufijo se++
une más fuerte que la desreferencia*
, y eso sucede antes del prefijo++
debido al orden). Los paréntesis solo son necesarios cuando necesita el valor antes de incrementarlo(*p++)++
. Si elige todos los prefijos,++*++p
también funcionará bien sin paréntesis (pero incrementa el valor al que se apunta después del incremento del puntero).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);
fuente