puntero a array

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

puntero a array

Notapor migueleitorone » Jue Oct 21, 2010 6:45 pm

buenas, estoy haciendo una funcion para generar un mapa en consola solo tengo esto y no se seguir:
Código: Seleccionar todo
char* generar_mapa( int alto, int ancho )
{
   char* array_mapa = new char[alto][ancho];

   for(int i=0; i<alto; i++)
   {
      for(int j=0; j<ancho; j++)
/////////////////////////////////////////////////>>>> Segun he leido tengo que escribir "*array_mapa" para acceder al primer elemento, *array_mapa +1 para acceder al segundo, etc. pero el unico ejemplo que tengo es de un array unidimensional. Como lo hago con uno de dos??



   }
}


gracies
migueleitorone
 
Mensajes: 88
Registrado: Mié Ago 18, 2010 2:59 pm
Ubicación: Barcelona, España

Re: puntero a array

Notapor Juanxo » Jue Oct 21, 2010 7:59 pm

cuidao. La variable que estás declarando es un puntero, por lo que solo puede tomar arrays unidimensionales. Para crear en tiempo de ejecución arrays bidimiensionales, sería así:

Código: Seleccionar todo
char** mapa = new char*[alto];
for (int i = 0; i < alto; ++i)
  mapa[i] = new char[ancho];


Y para acceder, puedes usar una manera mucho más simple

Código: Seleccionar todo
for (int i = 0; i < alto; ++i)
{
  for (int j = 0; j < ancho; ++j)
    std::cout << mapa[i][j];
}


Hay una manera que suele ser más eficiente, sobre todo cuando tratamos con tipos que no sean básicos(es decir, tipos que sean clases o structs)
Código: Seleccionar todo
char** puntero_a_fila = mapa;
for (int i = 0; i < alto; ++i, ++puntero_a_fila)
{
  char* puntero_a_columna = *puntero_a_fila;
  for (int j = 0; j < ancho; ++j, ++puntero_a_columna)
    std::cout << *puntero_a_columna;
}
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: puntero a array

Notapor migueleitorone » Vie Oct 22, 2010 12:26 pm

Ahh pensaba que se con un puntero a array podia crear arrays dinamicos multidimensionales.
Por lo que he mirado en google, tu solucion es usar punteros dobles no? Te agradezco la ayuda pero no entiendo ni papa del codigo que me has escrito, de hecho estaba haciendo este ejercicio para practicar el tema de la memoria dinamica, y me da la sensacion de que si me pongo con los punteros dobles me voy a hacer un buen lio xdd.

Visto lo visto estoy intentado hacer lo mismo pero con un array unidimensional, calculado el area del mapa ( ancho * alto ) este es el nuevo codigo, que me tira errores cuando intento darle un valor a las "paredes" del mapa:

Código: Seleccionar todo
char* generar_mapa( int alto, int ancho )
{
   int area = alto * ancho;
   char* array_mapa = new char[area];

   for(int i=0; i < area; i++)
   {
      if( i >= 0 && i <= ancho-1) *array_mapa+i = '-';
      else if( i >= ((area-1) -(ancho-1)) && i <= area-1) *array_mapa+i = '-';  /* error C2106: '=' : el operando izquierdo debe ser valor L ->>> edito: solo me salta el error si lo hago de esta forma, con array_mapa[i] no me aparece dicho error*/
      else
      {
         for(int j=1; j<= alto-2; j++)
         {
            if( i == ancho*j )  /*/////////////////////por otro lado.. tengo un pequeño problema para organizar el codigo, aqui necesito un else if, para seguir descartando posibilidades en la siguiente verificacion y tener un ultimo else para dar el valor espacio(" ") a las casillas que no sean paredes, pero necesito tambien el bucle for, como puedo hacer esto? */
            {
               *array_mapa+i = '|';
               break;
            }
         }
      }
      for(int j=2; j<= alto-1; j++)
         {
            if( i == ancho*j-1 )
            {
               *array_mapa+i = '|';
               break;
            }
         }
   }

   return array_mapa;
}
migueleitorone
 
Mensajes: 88
Registrado: Mié Ago 18, 2010 2:59 pm
Ubicación: Barcelona, España

Re: puntero a array

Notapor Juanxo » Vie Oct 22, 2010 1:40 pm

buenas miguel:

vayamos por partes. El primer error que te tira es por lo siguiente:

cuando haces *array_mapa, estás accediendo al primer valor. Tu lo que quieres es acceder al valor i, por lo que tienes que cambiar *array_mapa + i, ya que te lo esta procesando como *(array_mapa) + i, lo que sería el VALOR de la posicion 0 + i. Cambialo por *(array_mapa+i), lo que sería como acceder al valor en la posicion "i". Pero no se porque no usas [i], que da el mismo resultado y es mucho más claro.

Aunque tengas un array unidimensional, existe la opción de recorrerlo con un bucle doble de una manera más simple:
Código: Seleccionar todo
// Por lo que he visto, quieres tener un mapa tal que:
----------
|         |
|         |
----------

Para ello hacemos:

Código: Seleccionar todo
    char* generar_mapa( int alto, int ancho )
    {
       int area = alto * ancho;
       char* array_mapa = new char[area];

       for(int i=0; i < alto; i++)
       {
         int pos_fila = i * altura; // así calculamos la posicion dentro del array en el que empieza  la fila
         for (int j = 0; j < ancho; j++)
         {
            int pos = pos_fila + j;
            if ( i == 0 || i == (alto - 1) ) // Estamos en una de las paredes horizontales
               array_mapa[pos] = '-';
            else if ( j == 0 || j == (ancho - 1) ) // Estamos en una pared
               array_mapa[pos] = '|'
            else // Estamos en un lugar vacío
               array_mapa[pos] = ' ';
         }
       } 
       return array_mapa;
    }
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: puntero a array

Notapor migueleitorone » Vie Oct 22, 2010 2:23 pm

Juanxo escribió:cuando haces *array_mapa, estás accediendo al primer valor. Tu lo que quieres es acceder al valor i, por lo que tienes que cambiar *array_mapa + i, ya que te lo esta procesando como *(array_mapa) + i, lo que sería el VALOR de la posicion 0 + i. Cambialo por *(array_mapa+i), lo que sería como acceder al valor en la posicion "i". Pero no se porque no usas [i], que da el mismo resultado y es mucho más claro.

De hecho estaba usando [i] pero no queria dejarlo sin saber que pasaba con la otra manera.

Pues si que es sencillo de la manera que dices, madre mia como me he liado.
Lo habia completado usando una funcion que devolviera true o false para para verificar cada pared:
Código: Seleccionar todo
char* generar_mapa( int alto, int ancho )
{
   int area = alto * ancho;
   char* array_mapa = new char[area];

   for(int i=0; i < area; i++)
   {
      if(p_arriba(alto, ancho, i)) array_mapa[i] = '-';
      else if (p_abajo(alto, ancho, i, area)) array_mapa[i] = '-';
      else if (p_izquierda(alto, ancho, i)) array_mapa[i] = '|';
      else if (p_derecha(alto, ancho, i)) array_mapa[i] = '|';
      else array_mapa[i] = ' ';
   }

   return array_mapa;
}


muchas gracias de nuevo juanxo :D
migueleitorone
 
Mensajes: 88
Registrado: Mié Ago 18, 2010 2:59 pm
Ubicación: Barcelona, España

Re: puntero a array

Notapor carlostex » Mar Oct 26, 2010 3:07 am

Bueno a mi me enseñaron otra forma de manejar array multidimencionales, que es declarar un solo puntero, y hacer unas conversiones para transformar de una notación n-dimencional a la del array.
Explico con un ejemplo
Código: Seleccionar todo
int filas=3, cols=2;
int *matriz;
matriz=new int[filas*cols];
for(int x=0;x<cols;x++)
    {
    for(int y=0;y<filas;y++)
          {
              int num=matriz[y*cols+x];//Accede a la coordenada x,y

           }
     }


Si quisieras hace lo contrario, partir del índice y obtener las coordenada, solo hay que hacer una divisiones:
x=i%cols;
y=i/cols;

donde i es el índice al que deseas acceder.

Al principio puede parecer tedioso, pero en realidad es muy fácil una vez que te acostumbras.
El hecho de manejarlo así es que cuando se declara int **matriz; y les asignas memoria en realidad se crean varias filas de memoria que pueden estar en distintos lados y esto hace que el acceso sea mas lento, en cambio al declararlo todo junto es mas rápido, también depende de como lo uses por que hacer esas divisiones puede tomas el mismo tiempo que acceder a los bloques de memoria por separado, pero bueno, por alguna razón, en los motores gráficos usan arrays y no matrices para guardar píxeles.
Si usas c++ para hacer lo que comentaste con memoria dinámica, los operadores new y delete te facilitan mucho la vida.
y en realidad apuntadores es fácil una ves que entiendes que son.
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron