PDA

Visualizza la versione completa : [C] Puntatori a matrici di struttura


Lak3d
07-11-2006, 15:09
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.




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.

zero85
07-11-2006, 16:12
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].



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


#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;
}

Lak3d
07-11-2006, 16:21
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...

Lak3d
07-11-2006, 17:49
nessuno che mi chiarisca le idee? :D

rsdpzed
08-11-2006, 11:59
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)


#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] ;)

Lak3d
08-11-2006, 15:17
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)... :)

rsdpzed
08-11-2006, 16:45
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.

Lak3d
08-11-2006, 17:40
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...


#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++;
}
}

Lak3d
08-11-2006, 18:07
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? :mame:

zero85
08-11-2006, 18:18
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


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

Loading