[C con Clase] Prioridad operadores. Punteros a struct
Davidson, Steven
srd4121 en njit.edu
Lun Abr 21 19:40:50 CEST 2014
Hola Marving,
2014-04-21 12:12 GMT-04:00 Marving <jr.marving en gmail.com>:
> Hola.
> Trasteando con los operadores y punteros a struct. Tengo un par de dudas,
> relacionadas con los resultados obtenidos, y me gustaría que me ayudaseis
> a conocer la lógica de los operadores . . .
>
Hay un error en tu código fuente, al escribir:
ptr_strct->nombre = "Bjarne Stroustrup";
Esto no es correcto porque 'nombre' es de tipo 'char *', mientras que la
cadena literal, "Bjarne Stroustrup", es de tipo 'const char *'. Por lo
tanto, estás realizando esta asignación:
char * = const char *
Esto no se permite, porque podríamos modificar el contenido apuntado,
cuando tal contenido es de sólo-lectura.
Para este ejemplo, aconsejo apuntar a una cadena modificable. Por ejemplo,
char szNombre[] = "Bjarne Stroustrup";
ptr_strct->nombre = szNombre;
[CORTE]
En la siguiente línea, según lo que tengo entendido
> cout <<"*ptr_strct++->nombre " << *ptr_strct++->nombre << endl;
> Tenemos el operando ptr_strct
> sobre el operan los operadores
> * y ++->
>
Para dejar las cosas claras, la subexpresión consiste de 3 operadores:
*, ++, y ->
Operador unario postincremento ++ tiene la misma prioridad que -> seleccion
> miembros apuntador
> * desreferencia tiene menor prioridad
>
Conflicto entre ++->. Tienen asociatividad izquierda derecha. Entonces
>
Esto no es del todo correcto. El operador -> tiene mayor precedencia,
mientras que los operadores * y ++ tienen la misma precedencia.
Como el operador -> requiere dos operandos y el primero es un operador,
implícitamente tenemos que realizar esta subexpresión del operador ++.
1º ptr_strct++->nombre // aumento el puntero char* nombre
> 2 *((ptr_strct++)->nombre) // lee el contenido de ese puntero
> j
>
>
El orden es:
1º : ptr_strct++
2º : 1º -> nombre
3º : * 2º
O con paréntesis,
* ( (ptr_strct++) -> nombre )
Sin embargo lo que parece que hace es
> 1º ptr_strct->nombre
> 2º *(ptr_strct->nombre) // B
> 3º ptr_strct++ // Aumenta ptr_strct su sizeof
>
>
Bueno, esto es el efecto de las operaciones. Recuerda que estamos usando el
operador ++ de postincremento. Por lo tanto, el efecto del incremento se
realizará después de evaluar la expresión.
---------------------------------------------------------------------
> En la siguiente línea según lo que tengo entendido
> cout << ++*ptr_strct->nombre << endl;
> Tenemos el operando ptr_strct
> sobre el operan
> ++* y ->
>
Nuevamente, por claridad, tenemos 3 operadores:
++, *, y ->
y 2 términos (no son operadores):
ptr_strct y nombre
-> tiene mayor prioridad que preincremento ++ y desreferencia *
> 1º ptr_strct->nombre
> Conflicto entre ++**. Tiene asociatividad derecha izquierda
> 2º *(ptr_strct)->nombre; // 'B'
> 3º ++(*(ptr_strct)->nombre); // ++'B'
>
> Podría haber aparecido algun mensaje del tipo lvalue required ++
>
No; en este caso no, porque sí tiene un valor modificable: nombre[0], que
pasaría a ser 'C'. Es decir, el comportamiento de ++ en este caso es
equivalente al de esta expresión:
*ptr_strct->nombre = *ptr_strct->nombre + 1;
Sin embargo aparece el mensaje
> RUN FINISHED; Segmentation fault; core dumped; real time: 400ms; user:
> 0ms; system: 0ms
>
Este error del sistema operativo tiene que ver con el hecho de que has
accedido a memoria que no reservaste, a consecuencia de esta
operación: 'ptr_strct++',
por luego intentas acceder a 'nombre' tanto para lectura como para
escritura.
Supongo que ya lo sabes, pero por si acaso no es así, el capítulo 14 del
curso de C++ habla de la precedencia de operadores; puedes dirigirte a:
http://c.conclase.net/curso/index.php?cap=014#inicio
Espero haber aclarado las dudas.
Steven
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20140421/60ccbc2b/attachment.html>
Más información sobre la lista de distribución Cconclase