Duda con correspondencia entre arreglos y punteros en C++

Iniciado por retr02332, 2 Junio 2020, 18:39 PM

0 Miembros y 1 Visitante están viendo este tema.

retr02332

Hola a todos, de nuevo...

Me disculpo por preguntar dos veces seguidas, en realidad antes de preguntar de nuevo, me tome la molestia de googlear mucho. Pero realmente sentí que se contradecían las cosas, así que decido volver a preguntar, pero repito.. siento preguntar dos veces seguidas.

Bueno, el código es el siguiente:


#include<iostream>
using namespace std;

int main(){
   int numeros[] = {1,5,9,7,4,3};
   int *dir_numeros;

   dir_numeros = &numeros[0]; // Tambien, por simplicidad podemos colocar 'números', en lugar de '&numeros[0]'

   for(int i=0; i < 6; i++){
       cout<<*dir_numeros++;
   }

   /*
   cout<<*dir_numeros;
   dir_numeros++;
   cout<<*dir_numeros;
   */

   return 0;
}


Tanto lo que esta comentado, como el for que esta en el main, me imprimen lo siguiente:

Citar
159743

Lo que estoy haciendo, es simplemente mostrar los valores del arreglo, pero esta vez, haciendo uso de punteros.

Para no hacer esto tan largo, la duda de acuerdo a lo anterior es la siguiente:

int numero = 5;
int *dir_numero = &numero;

cout<<*dir_numero; "Esto imprime el valor"
cout<<dir_numero; "Esto imprime la dirección de memoria de la variable a la que apunta"

Teniendo eso claro, como es posible que en el for se use el ++ "de incremento" y este me imprima los valores del array?, es decir... Si uno se fija, ahí se esta usando el *, por lo que debería incrementar en uno dicho valor (1++) "porque la dirección que almaceno es la del primer elemento del array, por eso el 1".

En cambio, si vemos lo que esta comentado, es algo que hice yo, que funciona igual, pero que para mi tiene lógica. Porque esta vez lo que incremento es la dirección de memoria a la que apunta el puntero (mas que incrementar, es como seguir a la siguiente dirección de memoria, pues un arreglo almacena los datos de forma contigua, y claro... ahora sí recorrería el arreglo lógicamente.

entonces:

¿Porque el for hace lo mismo que lo que esta comentado, si este lo que incrementa es el valor del arreglo y no su dirección de memoria?

Muchas gracias, y perdón por extenderme.

RayR

El operador ++ tiene mayor precedencia que el *, por lo que primero se incrementa el puntero y luego se "desreferencia". En cambio así:

Código (cpp) [Seleccionar]
(*dir_numeros)++

incrementas el valor.

Eternal Idol

#2
Cita de: clay2332xd en  2 Junio 2020, 18:39 PMTeniendo eso claro, como es posible que en el for se use el ++ "de incremento" y este me imprima los valores del array?, es decir... Si uno se fija, ahí se esta usando el *, por lo que debería incrementar en uno dicho valor (1++) "porque la dirección que almaceno es la del primer elemento del array, por eso el 1".

A cout se le pasa como argumento *dir_numeros y despues se incrementa dir_numeros.

Distinto seria si hicieras:
Código (c++) [Seleccionar]
cout<<(*dir_numeros)++;

Cita de: clay2332xd en  2 Junio 2020, 18:39 PM¿Porque el for hace lo mismo que lo que esta comentado, si este lo que incrementa es el valor del arreglo y no su dirección de memoria?

El for tambien incrementa el puntero.




Cita de: RayR en  2 Junio 2020, 18:59 PM
El operador ++ tiene mayor precedencia que el *, por lo que primero se incrementa el puntero y luego se "desreferencia".

Si eso fuera cierto el primer numero en salir seria 5 y el ultimo vaya uno a saber. que es lo que pasa con este codigo:

Código (c++) [Seleccionar]
for(int i=0; i < 6; i++){
++dir_numeros;
       cout<<*dir_numeros;
   }


El codigo original es en realidad de este estilo:
Código (asm) [Seleccionar]
00007ff7`a615358a 488b442428      mov     rax,qword ptr [rsp+28h] ;rax=dir_numeros
00007ff7`a615358f 8b00            mov     eax,dword ptr [rax] ds:000000f1`867cfa40=00000001 ;eax=*dir_numeros
00007ff7`a6153591 89442424        mov     dword ptr [rsp+24h],eax
00007ff7`a6153595 8b542424        mov     edx,dword ptr [rsp+24h] ;p2
00007ff7`a6153599 488d0d70930e00  lea     rcx,[merr!std::cout (00007ff7`a623c910)] ;p1
00007ff7`a61535a0 e8dce0feff      call    merr!ILT+1660(??6?$basic_ostreamDU?$char_traitsDstdstdQEAAAEAV01HZ) (00007ff7`a6141681)
00007ff7`a61535a5 488b442428      mov     rax,qword ptr [rsp+28h] ;rax=dir_numeros
00007ff7`a61535aa 4883c004        add     rax,4 ;rax += 4 (es un int, 4 bytes)
00007ff7`a61535ae 4889442428      mov     qword ptr [rsp+28h],rax ;dir_numeros=rax
00007ff7`a61535b3 ebc3            jmp     merr!main+0x68 (00007ff7`a6153578)
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

RayR

Cierto, fue un resbalón escribit que primero se incrementa. Lo que quise decir es que, dada la precedencia de operadores, primero se evalúa la expresión dir_numeros++ (que, al tratarse de postincremento, nos da el valor actual de dir_numeros), esto se desreferencia, y después se incrementa el puntero.