2012-02-20 17 views
5

Puede alguien explicar la salida del siguiente códigopuntero a puntero aritmética

char* a[] = {"ABC123", "DEF456", "GHI789"}; 
char **p = a; 
cout<<++*p<<std::endl; 
cout<<*p++<<std::endl; 
cout<<++*p<<std::endl; 

Salida:

BC123 
BC123 
EF456 

Lo que es confuso para mí es el diferente comportamiento de ++ * py * p ++. Esperaba que la salida fuera:

ABC123 
DEF456 
GHI789 
+6

La precedencia de operadores. Agregue algunos paréntesis y se aclarará ... – jrok

Respuesta

3
char* a[] = {"ABC123", "DEF456", "GHI789"}; 
char **p = a; 
cout<<++*p<<std::endl; // 1 
cout<<*p++<<std::endl; // 2 
cout<<++*p<<std::endl; // 3 

En la línea 1 primero *p estará apuntando a la elemento de la matriz "ABC123" y los ++ mueve uno hacia adelante y así 'FC123' se imprime.

En la línea 2 *p todavía está señalando a BC123 por lo que este se imprime y luego una vez impreso el ++ se lleva a cabo. Esto mueve el puntero al segundo elemento de la matriz

En la línea 3 es lo mismo que la línea 1. Has tomado el contenido de p (ahora el segundo elemento de la matriz) y moviste un carácter en esa cadena, imprimir tanto EF456

(también echar un vistazo a aquí Pointer arithmetic on string type arrays, how does C++ handle this? como yo creo que puede ser útil para conseguir una comprensión de lo que está sucediendo)

para imprimir lo que espera el siguiente funcionaría:

cout<<*p++<<std::endl; 
cout<<*p++<<std::endl; 
cout<<*p++<<std::endl; 

O

cout<<*p<<std::endl; 
cout<<*(++p)<<std::endl; 
cout<<*(++p)<<std::endl; 

O varias otras maneras (teniendo en cuenta la precedencia como han dicho otros)

0

++*p se ejecuta antes de la impresión. Así que incremente el puntero, luego imprima. *p++ se ejecuta después de la impresión. Imprimir, luego incrementar

0

Solo supongo, pero creo que debido a que está incrementando el puntero de referencia usando cout<<++*p<<std::endl;, lo que realmente está haciendo es incrementar el carácter al inicio de la cadena que p apunta y luego enviarlo a la salida estándar.

De manera similar, cout<<*p++<<std::endl; está incrementando el carácter después de la salida, por lo que el cout<<++*p<<std::endl; final da como resultado dos incrementos.

deberías probar este lugar y ver si funciona

cout<<*(++p)<<std::endl; 
cout<<*(p++)<<std::endl; 
cout<<*(++p)<<std::endl; 
+1

La última línea de esa salida ocasiona que se active repentinamente. El '++ p' lo está moviendo más allá del final del arreglo – Firedragon

4

Tal vez esto ayude. Usted ejemplo es más o menos equivalente a esto:

++(*p); 
cout << *p << '\n'; 

cout << *p << '\n'; 
++p; 

++(*p); 
cout << *p << '\n'; 

Sin paréntesis, *p++ se analiza como *(p++) desde el sufijo de la subasta tiene mayor precedencia que el operador eliminar la referencia. Sin embargo, el incremento todavía se hace después de toda la expresión.

Por otro lado, el incremento de prefijo y * tienen la misma precedencia, por lo que ++*p se analiza de derecha a izquierda como ++(*p). Sabiendo que el incremento de prefijo debe hacerse antes de la expresión, ahora puede juntar toda la imagen.

+0

Lo tengo ... Solo estaba tomando precedencia de operador en la imagen, olvidándome por completo de la asociatividad ... Gracias –

1

Según la tabla de precedencia del operador C++, la precedencia del incremento posterior es mayor que el operador de desreferencia (*), y el operador de preincremento y desreferencia tiene la misma precedencia. También el operador de preincremento y desreferencia son asociativos de derecha a izquierda.

Por lo tanto, en la primera línea (cout<<++*p<<std::endl;), * y ++ se evalúan de derecha a izquierda (primera desreferencia, luego incremento). Ahora p aún apunta a la primera matriz (porque no ha cambiado), pero (* p) apunta a la segunda letra de la primera cadena (el resultado muestra este hecho).

En segunda línea (cout<<*p++<<std::endl;) sin embargo de incremento posterior se evalúa primero (después de recuperar el valor antiguo de p) y la p se incrementa y apunta ahora a la segunda matriz. Pero antes del incremento, el valor de p se usa en la expresión y la salida de la segunda línea es exactamente como la primera línea.

En la tercera línea, primero se desreferencia el p (señale la primera letra de la segunda matriz), luego se incrementa (señale la segunda letra de la segunda matriz) y se imprime el valor.

Cuestiones relacionadas