[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