¿Qué diferencia hay entre while (* p) {p ++;}, while (* ++ p) {;} y while (* p ++) {;}?

Se trata de la función strcat .

 while (*p) p++; 

y

 while (*++p) ; 

ambos trabajos, pero

 while (*p++) ; 

No funciona. Creo que primero y tercero deberían ser iguales, pero no lo es.

Ambos

 while (*p) p++; 

y

 while (*++p) ; 

avanzará p para apuntar al terminador 0 en una cadena, mientras que

 while (*p++) ; 

avanzará p para apuntar un carácter más allá del terminador 0.

Para ver por qué, vamos a asumir los siguientes caracteres en la memoria:

 Address 0x00 0x01 0x02 0x03 ------- ---- ---- ---- ---- 0x8000 'a' 'b' 'c' 0 0x8004 ... 

Supongamos que p comienza en la dirección 0x8000. Así es como se desarrolla el primer bucle:

 1. *p = 'a' 2. p = 0x8001 3. *p = 'b' 4. p = 0x8002 5. *p = 'c' 6. p = 0x8003 7. *p = 0 8. end loop 

Así es como se desarrolla el segundo bucle:

 1. p = 0x8001 2. *p = 'b' 3. p = 0x8002 4. *p = 'c' 5. p = 0x8003 6. *p = 0 7. end loop 

Y aquí está el último:

 1. *p = 'a' 2. p = 0x8001 3. *p = 'b' 4. p = 0x8002 5. *p = 'c' 6. p = 0x8003 7. *p = 0; 8. p = 0x8004 9. end loop 

En la última versión, evaluar *p++ avanza el puntero incluso si el valor de *p es 0.

Supongamos que p es una cadena.

 while (*p) p++; /* (1) */ while (*++p) ; /* (2) */ while (*p++) ; /* (3) */ 
  • (1) es diferente de (2) si p es una cadena vacía.
  • (1) es diferente de (3) porque con (3) , incluso si el valor actual de *p es un carácter '\0' , p se incrementa.
 // move p forward as long as it points to a non-0 character, // leave it pointing to a 0 character. while (*p) p++; // move p forward until it points to a 0 character, skipping the first // character before you start while (*++p); // move p forward until it points one past a 0 character while (*p++); 

Entonces, dado que (1) “funciona”: (2) también funciona si p inicialmente apunta a una cadena no vacía. (3) no funciona en absoluto porque p termina apuntando a un lugar diferente.

*++p incrementa p y luego evalúa a lo que p apunta ahora. *p++ evalúa a lo que p apunta inicialmente, pero también incrementa p . Por lo tanto (2) y (3) son diferentes.

(1) y (3) son diferentes porque (3) ejecuta el p++ , luego decide si parar. (1) primero mira a *p para decidir si parar o no, y si no se detiene, ejecuta p++ .

* ++ p significa incrementar esta variable, luego usarla
* p ++ significa usar la variable, luego incrementarla