Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035

    [C] Puntatori a matrici di struttura

    Visto che nessuno mi risponde di là e siccome è meglio non usare thread altrui, ecco che apro un nuovo thread...

    finora non mi era mai capitato di dover usare puntatori a matrici (di struct) e pensavo funzionasse tutto come nel caso di un vettore unidimensionale... invece non funzionna... e dopo diverse ricerche su gugl non sono riuscito a venirne a capo da solo.


    codice:
    struct esempio{
       int a;
       int b;
    };
    
    typedef esempio Esempio;
    Esempio c[1][3]={1,2,3,4,5,6};
    Esempio *ptr;
    
    ptr=c[3];
    
    printf("%d", ptr[1][1].a);
    Il puntatore accetta soltanto una dimensione (quella delle colonne ovviamente), mentre è la printf che non accetta quella forma a puntatore con indice, ma non solo, rifiuta anche qualsiasi altra forma possibile e immaginabile (puntatore +offset ecc) che ho provato.

  2. #2
    codice:
    ptr=c[3];
    Primo errore: c è dichiarato come matrice di 1X3 ma ricorda che gli indici partono da 0 quindi con se tenti di acedere con l'indice 3 vai fuori range dell'array.

    Secondo errore: per il compilatore non è ovvio come è per l'uomo che se l'array ha una sola riga deve andare a pescare automaticamente la terza colonna; in questo caso al puntatore viene assegnato l'indirizzo della terza riga (in quanto non specifichi la colonna) dell'array che ovviamente punta a una locazione ben diversa da quella di c[0][2].

    codice:
    printf("%d", ptr[1][1].a);
    Primo errore: ptr è un puntatore a UNA struttura di tipo Esempio non ad un array quindi l'accesso attraverso l'operatore[] non ha senso

    Secondo errore: devi dereferenziare il puntatore prima di stamparlo altrimenti stampi il valore del puntatore non il valore puntato.

    Il tutto modificato dovrebbe avere un aspetto simile
    codice:
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char **argv)
    {
       struct esempio{
              int a;
              int b;
       };
        
        typedef esempio Esempio;
        Esempio c[1][3]={1,2,5,6,10,11};
        printf("Indirizzo di c[0][2] in hex: %X\n\n", &c[0][2]);
        printf("Valore del membro a di c[0][2]: %d\n\n", c[0][2].a);
        
        Esempio *ptr;
        ptr=&c[0][2]; //Assegno al puntatore il riferimento a c[0][2]
        
        printf("Indirizzo di ptr in hex: %X\n\n",ptr);
         
        printf("Valore puntato da prt: %d\n", (*ptr).a);
        //metodo alternativo di dereferenziamento con operatore ->
        //printf("Valore puntato da prt: %d\n", ptr->a);
        system("pause");
        return 0;
    }

  3. #3
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    io facevo puntare ptr a c[3] semplicemente per indicargli che la matrice occupava 3 colonne.

    Quello che però non capisco è perchè non sia possibile usare la forma ptr[1][2].a
    Eppure con un vettore unidimensionale la forma ptr[n].membro mi pare che sia accettata... la dereferenziazione c'è sempre, solo che uso la notazione con indice di vettore... è un vettore di struttura...

    e poi, dov'è che gli specifico chiaramente di quante colonne è fatta la matrice per permettergli di gestire correttamente gli scostamenti?

    fra l'altro il tuo codice mi da una serie infinita di warnings in fase di compilazione...

  4. #4
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    nessuno che mi chiarisca le idee?

  5. #5
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    a parte che zero85 ti ha dato una serie di info esatte che dovresti usare per rifletterci un po su, penso che cio che vuoi sapere sia questo

    (usando il codice di zero85)
    codice:
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char **argv)
    {
       typedef struct esempio{
              int a;
              int b;
       } Esempio;
        
        Esempio c[1][3]={1,2,5,6,10,11};
        printf("Indirizzo di c[0][2] in hex: %X\n\n", &c[0][2]);
        printf("Valore del membro a di c[0][2]: %d\n\n", c[0][2].a);
        
        Esempio *ptr;
        ptr=c[0];   
        
        printf("Indirizzo di ptr in hex: %X\n\n",&ptr[2].a );
         
        printf("Valore puntato da prt: %d\n", ptr[2].a );
    
        system("pause");
        return 0;
    }
    Puoi accedere ad un array anche con un puntatore ad un suo elemento ma devo utilizzarlo come un puntatore ergo nn puoi usare l'operatore [] come ti suggeriva prima zero.
    Inoltre al C nn gli devi "indicare" nulla specialmente con un assegnazione fuori range come p = c[3]

  6. #6
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    allora: non è questione di non aver capito come funzioni, è questione di non capire perchè con array ad una dimensione vada benissimo la forma con puntatore e indici dell'array, mentre con uno a 2 dimensioni questa forma (ptr[][].a) non sia accettata.

    Il mio c[3] era semplicemente un tentativo (alla luce di quanto scritto sopra) di far conoscere al puntatore di quante COLONNE è composta la matrice, permettendogli così, quando si trova a dover gestire una notazione con indice di vettore, di sapere quanti scostamenti effettuare per restituirmi il giusto valore richiesto.
    Ma visto che quanto sopra non è possibile farlo, beh, allora cade tutto. Rimarrebbe da capire però quanto ho scritto all'inizio... (ovvero come mai quella forma non è accettata con vettori bidimensionali)...

  7. #7
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    perchè ptr è un puntatore ad un array monodimensionale non un puntatore ad una matrice,
    quando tu scrivi
    ptr = c[i];
    stai facendo puntare ptr al primo elemento della riga i-esima della matrice e da quel momento in poi ptr lo potrai usare solo come puntatore a quell'array: la riga i della matrice.
    Oltre a ciò non fai null'altro. Al C non gli fai "capire" niente... è C non excel.
    Non solo...puoi addirittura scrivere una cavolata tipo ptr=c[3] e per lui scrivi una cosa normale semplicemente ti restituisce il puntatore ad una porzione di memoria che non hai nemmeno allocato e chissa a cosa punta.

  8. #8
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    scusa eh, la matrice in memoria è comunque un array monodimensionale... ma se non ne conosce il nuemero di colonne come saprà spostarsi correttamente all'elemento n della riga successiva? Certo che non è Excel, ma guardacaso passando un vettore a + dimensioni ad una funzione l'indice delle righe non occorre, ma servono tutti quelli successivi... per quale motivo? semplice, deve conoscere l'esatto numero di elementi per ogni riga (il numero di colonne) se vogliamo che sia in grado di restituirmi elementi appartenenti alle righe successive..

    da quel momento in poi ptr lo potrai usare solo come puntatore a quell'array: la riga i della matrice.
    Scusami se metto in dubbio quello che affermi, ma facendo puntare il puntatore al primo elemento della matrice, posso tranquillamente spostarmi (usando l'aritmetica dei puntatori) su tutti gli elementi della matrice, e questa è di n righe...

    codice:
    #include <stdio.h>
    
    struct prova{
       int a;
       int b;
    };
    
    void function(struct prova *ptrP);
    
    int main(){
    int i,j;
    struct prova b[2][3]={ {3,4,6,7,4,9}, {2,4,5,6,7,8} };
    
    function(b[0]);
    
    for (j=0; j<2; j++)
       for (i=0; i<3; i++){
          printf("%d-",b[j][i].a);
          printf("%d\n",b[j][i].b);
       }
    
    return 0;}
    
    
    void function(struct prova *ptrP){
    int i;
       for (i=0; i<6; i++){
          (ptrP)->a=23;
          (ptrP)->b=23;
          ptrP++;
       }
    }

  9. #9
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    Insomma, mi pare di capire che se passo l'intero vettore bidimensionale ad una funzione gli devo indicare la dimensione del secondo indice, se lo passo ad un puntatore, non essendo valida la notazione con due indici (ptr[][]), devo usarne uno soltanto muovendomi per la dimesnione globale della matrice... giusto?

  10. #10
    Esatto c'è solo una piccola imprecisione:
    soltanto muovendomi per la dimesnione globale della matrice
    questo nel caso che il puntatore punti alla prima locazione altrimenti ti puoi muovere solo di globale - posizione iniziale del puntatore:

    esempio
    codice:
    int a[5][8]={bla,bla,bla};
    int *ptr;
    ptr = a[2];
    in questo caso potrai accedere al massimo a ptr[23] (meglio puoi accedere anche a ptr[10^6] ma otterresti valori del tutto casuali) questo perchè la matrice iniziale conteva 40 elmenti alla quale ne devi sottrarre 16 in quanto ptr punta alla 16^ (2 righe * 8 colonne) locazione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.