SoloCodigo

Programación General => C/C++ => Mensaje iniciado por: leusss en Miércoles 25 de Agosto de 2010, 06:52

Título: Arreglos de punteros.
Publicado por: leusss en Miércoles 25 de Agosto de 2010, 06:52
Hola.

 Resulta que estuve leyendo lo más detenidamente el K&R y me encuentro en la parte de punteros (supongo yo la parte más importante de todo el lenguaje C).

 Quiero ver si entendí bien cuál es la noción de matrices (Arreglos bidimensionales) y su relación con los punteros, porque hice un programa que por donde lo vea pienso que debería andar pero no anda.

 Veamos: Sé que un puntero es una variable que indica la dirección de memoria de otra variable (a la cual "apunta"). Se también, que en los arreglos las direcciones de memoria son contiguas, es decir que si creo un puntero al primer elemento del arreglo, puedo obtener la dirección de los otros elementos del arreglo mediante sumas y, si es posible restas(por ejemplo si p es un puntero a int, p se puede tomar como la dirección del elemento 0, p+1 vendria a ser la dirección del elemento 1, etc).

 Ahora bien, si cada puntero podemos considerar que comienza en "el primer elemento de un arreglo", entonces yo podria pensar en hacer un arreglo de punteros para obtener un "arreglo de arreglos", lo cual simularía una matriz. Luego tendría un puntero a puntero, que me indicaría en qué fila estoy y después según a qué se encuentre apuntando el puntero fila tendría en qué columna estoy.

 En fin... resulta que busqué ejercicios para hacer en internet y uno decía "pida un número y luego imprima una matriz de nxn tal que el elemento a[j] es 1 si i y j son coprimos, y 0 de lo contrario".

 Esto es lo que hice:

 
Código: C
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. char son_coprimos(int x, int y)
  6. {
  7.    int i;
  8.    if(x<=1 || y<=1) return 1;
  9.    if((x%2 == 0) && (y%2 == 0)) return 0;
  10.    for(i=3; 2*i<=x;i+=2)
  11.       if((x%i == 0) && (y%i == 0)) return 0;
  12.    return 1;  
  13. }
  14.  
  15. void matriz_coprimos(char **m, int n)
  16. {
  17.    int i, j;
  18.    m = (char**) malloc(sizeof(char*) * n);
  19.    for(i=0;i<n;++i)
  20.       m[i] = (char*) malloc(sizeof(char) * n);
  21.      
  22.    for(i=0;i<n;++i)
  23.       for(j=0;j<n;++j)
  24.          m[i][j] = son_coprimos(i+1, j+1);
  25.        
  26. }
  27.  
  28. main()
  29. {
  30.    char **a, n, i, j;
  31.    scanf("%d", &n);            
  32.    
  33.    matriz_coprimos(a, n);
  34.    
  35.    for(i=0;i<n;++i)
  36.    {
  37.       for(j=0;j<n;++j)
  38.          printf("%d ", a[i][j]);
  39.       printf("n");
  40.    }
  41.      
  42. system("Pause");
  43. }
  44.  
  45.  

PD: Claramente mi SO es windows xD

Saludos y muchas gracias.
Título: Re: Arreglos de punteros.
Publicado por: Eternal Idol en Miércoles 25 de Agosto de 2010, 12:57
No lo mire mucho pero al compilar (como C) el VC++ da un warning crucial:
(32) : warning C4700: uninitialized local variable 'a' used

Para poder cambiar la direccion a la que apunta la variable a desde la funcion matriz_coprimos tenes que pasar la direccion de esta variable (&a) y no su valor como estas haciendo ahora.
Título: Re: Arreglos de punteros.
Publicado por: leusss en Miércoles 25 de Agosto de 2010, 13:37
Pero creo que esta bien pasar a, ya que sí indica la direccion. Es más, me tira un warning intentar pasar &a.
Título: Re: Arreglos de punteros.
Publicado por: Eternal Idol en Miércoles 25 de Agosto de 2010, 14:24
Esta mal, sin duda pero no me creas a mi, hacelo simple:

Código: C
  1. a = 0;
  2. matriz_coprimos(a, n);
  3. printf("El valor de a es: %.8Xrn", a);
  4.  

No podes simplemente pasar &a, tenes que cambiar la funcion tambien.
Título: Re: Arreglos de punteros.
Publicado por: leusss en Miércoles 25 de Agosto de 2010, 19:49
Osea, es verdad, parece no alterar a 'a', pero sigo sin entender por qué :brickwall: y cómo arreglarlo
Título: Re: Arreglos de punteros.
Publicado por: ivanmvega en Miércoles 25 de Agosto de 2010, 19:58
Chamo, intentá esto
declará char *a
pasalo funcion (&a);
y en la funcion recibílo
funcion (char **a)
Título: Re: Arreglos de punteros.
Publicado por: Eternal Idol en Jueves 26 de Agosto de 2010, 11:28
leusss: para poder escribir en la variable tenes que pasar su direccion, ahora la estas pasando por valor. &a y en la funcion ***.

ivanmvega: de esa manera pasas la direccion de un puntero y no de un doble puntero como el intenta.
Título: Re: Arreglos de punteros.
Publicado por: ivanmvega en Jueves 26 de Agosto de 2010, 17:20
Si tienes razon no lo estoy haciendo tal como lo puse..mira abajo te pongo como lo estoy haciendo

 char
         *lenstr,
         *resp,
         *item,
         *aux_item;
lxml_get_item_tag ( _data, N2B_REQUEST, "", i ,&resp);
        if ( resp == NULL )
        {
                printf("XML Syntax Errorn");
                ok = FALSE;
        }

int lxml_get_item_tag ( char *xml, char *tag, char *atributos, int posicion, char** res )
{
    char
            *ini,
            *fin,
            tag_entrada     [512],
            tag_salida      [512],
            tag_aux         [512];

    int
            cantidad_renglones=0,
            len=0,
            tipo_xml= -1;

        memset ( tag_entrada, 0, sizeof (tag_entrada) );
        memset ( tag_salida, 0, sizeof (tag_salida) );
        memset ( tag_aux, 0, sizeof (tag_aux) );

        ini = xml;
        fin = xml;

        if ( (atributos) && strcmp(atributos, "NULL") !=0  && strcmp(atributos, "") )
                sprintf ( tag_aux, "%s %s", tag, atributos);
    else
                sprintf ( tag_aux, "%s", tag );

        if (lxml_search_symbol (ini, "&lt;") == TRUE )
                tipo_xml = TAG_POR_ENTIDAD;
        else if (lxml_search_symbol (ini, "<") == TRUE )
        tipo_xml = TAG_POR_CARACTER;

        sprintf ( tag_entrada, "%s",( char* ) lxml_open_tag( tag_aux, tipo_xml ) );

        sprintf ( tag_salida, "%s",( char* ) lxml_close_tag( tag, tipo_xml ) );

    while ( ( ini = strstr ( ini, tag_entrada ) ) != NULL && posicion > cantidad_renglones)
    {
                cantidad_renglones++;
                ini += strlen ( tag_entrada );
    }

        if ( ini == NULL )
        {
                *res = NULL;

                printf ( "Error. ini=NULL. No puedo seguirn" );
                exit ( EXIT_FAILURE );
        }

    fin = (char*) strstr ( ini, tag_salida );
    len = (fin - ini + strlen (tag_salida));

        // Reservo la memoria que necesito
        *res = (char*) malloc ( len );
        strncpy ( *res, ini, len );

        (*res) [ len ] = '';

    return len;
}