<div dir="ltr">Hola Marving,<div class="gmail_extra"><br><div class="gmail_quote">2014-04-21 12:12 GMT-04:00 Marving <span dir="ltr"><<a href="mailto:jr.marving@gmail.com" target="_blank">jr.marving@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hola.<br>
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<br>
a conocer la lógica de los operadores . . .<br></blockquote><div><br></div><div>Hay un error en tu código fuente, al escribir:<br><br><span style="font-family:arial,sans-serif;font-size:13px">ptr_strct->nombre = "Bjarne Stroustrup";</span><br>
</div><div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Esto no es correcto porque 'nombre' es de tipo '</span><span style="font-family:arial,sans-serif;font-size:13px">char *', mientras que la cadena literal, </span><span style="font-family:arial,sans-serif;font-size:13px">"Bjarne Stroustrup"</span><span style="font-family:arial,sans-serif;font-size:13px">, es de tipo '</span><span style="font-family:arial,sans-serif;font-size:13px">const char *'. Por lo tanto, estás realizando esta asignación:<br>
<br>char *  =  const char *</span></div><div><br></div><div>Esto no se permite, porque podríamos modificar el contenido apuntado, cuando tal contenido es de sólo-lectura.</div><div><br></div><div>Para este ejemplo, aconsejo apuntar a una cadena modificable. Por ejemplo,</div>
<div><br></div><div>char szNombre[] = <span style="font-family:arial,sans-serif;font-size:13px">"Bjarne Stroustrup";</span></div><div><br></div><div><span style="font-family:arial,sans-serif;font-size:13px">ptr_strct->nombre = </span>szNombre;<br>
</div><div><br></div><div><br></div><div>[CORTE]</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
En la siguiente línea, según lo que tengo entendido<br>
cout <<"*ptr_strct++->nombre " << *ptr_strct++->nombre << endl;<br>
Tenemos el operando ptr_strct<br>
sobre el operan los operadores<br>
*       y       ++-><br></blockquote><div><br></div><div>Para dejar las cosas claras, la subexpresión consiste de 3 operadores:<br>*,  ++,  y  -></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

Operador unario postincremento ++ tiene la misma prioridad que -> seleccion miembros apuntador<br>
* desreferencia tiene menor prioridad<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Conflicto entre ++->. Tienen asociatividad izquierda derecha. Entonces<br>
</blockquote><div><br></div><div>Esto no es del todo correcto. El operador -> tiene mayor precedencia, mientras que los operadores * y ++ tienen la misma precedencia.</div><div><br></div><div>Como el operador -> requiere dos operandos y el primero es un operador, implícitamente tenemos que realizar esta subexpresión del operador ++.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
1º      ptr_strct++->nombre             // aumento el puntero char* nombre<br>
2      *((ptr_strct++)->nombre)         // lee el contenido de ese puntero      j<br>
<br></blockquote><div><br></div><div>El orden es:<br><br>1º :    ptr_strct++</div><div>2º :    1º -> nombre</div><div>3º :    * 2º</div><div><br></div><div>O con paréntesis,</div><div><br></div><div>* ( (ptr_strct++) -> nombre )</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Sin embargo lo que parece que hace es<br>
1º      ptr_strct->nombre<br>
2º      *(ptr_strct->nombre)            // B<br>
3º      ptr_strct++                     // Aumenta ptr_strct su sizeof<br>
<br></blockquote><div><br></div><div>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.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
---------------------------------------------------------------------<br>
En la siguiente línea según lo que tengo entendido<br>
cout <<  ++*ptr_strct->nombre << endl;<br>
Tenemos el operando ptr_strct<br>
sobre el operan<br>
++*     y       -><br></blockquote><div><br></div><div>Nuevamente, por claridad, tenemos 3 operadores:<br><br>++,  *,  y  -></div><div><br></div><div>y 2 términos (no son operadores):<br><br>ptr_strct  y  nombre</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
-> tiene mayor prioridad que preincremento ++ y desreferencia *<br>
1º      ptr_strct->nombre<br>
Conflicto entre ++**. Tiene asociatividad derecha izquierda<br>
2º      *(ptr_strct)->nombre;           // 'B'<br>
3º      ++(*(ptr_strct)->nombre);       // ++'B'<br>
<br>
Podría haber aparecido algun mensaje del tipo lvalue required ++<br></blockquote><div><br></div><div>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:<br>
<br>*ptr_strct->nombre = *ptr_strct->nombre + 1;</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

Sin embargo aparece el mensaje<br>
RUN FINISHED; Segmentation fault; core dumped; real time: 400ms; user: 0ms; system: 0ms<br></blockquote><div><br></div><div>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: '<span style="font-family:arial,sans-serif;font-size:13px">ptr_strct++', por luego intentas acceder a 'nombre' tanto para lectura como para escritura.</span></div>
<div><br></div><div><br>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: <a href="http://c.conclase.net/curso/index.php?cap=014#inicio">http://c.conclase.net/curso/index.php?cap=014#inicio</a></div>
<div><br></div><div><br></div><div>Espero haber aclarado las dudas.</div><div><br></div><div>Steven</div><div><br></div></div></div></div>