Vai al contenuto

Primario: Sky Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Secondario: Sky Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Sfondo: Blank Waves Squares Notes Sharp Wood Rockface Leather Honey Vertical Triangles
Corsi di Laurea










ROX @ Unisa - Forum degli studenti di Ingegneria utilizza i cookie. Se prosegui la navigazione accetti il loro uso.    Accetto l'uso dei cookie
-->
Foto

puntatori e matrici


  • Effettua l'accesso per rispondere
Questa discussione ha avuto 27 risposta/e

#1
Marco De Rosa

Marco De Rosa

    Advanced Member

  • Utente
  • StellaStellaStella
  • 854 Messaggi:
Salve a tutti....volevo chiedere una cosa....ho provato a fare un semplice programma composto da 3 funzioni, una che caricasse da tastiera gli elementi di una matrice 3x3,una che li stampasse a video e una che calcolasse la media degli elementi nella matrice.....

L'unica cosa è che il programma volevo scriverlo utilizzando i puntatori e quindi non passando alle funzioni la matrice così come l'ho sempre passata ( con le parentesi quadre)....

Ho seguito la logica che una matrice essendo un array di array ed essendo l'array un puntatore ,la matrice dovrebbe essere tipo un puntatore ad un puntatore,quindi un doppio puntatore.....ma ho problemi nell'esecuzione del programma......se qualcuno ha dei suggerimenti....lo ringrazio....



#2
aRbok

aRbok

    Advanced Member

  • Utente
  • StellaStellaStella
  • 1517 Messaggi:
Ciao...senti io non ho mai pensato di fare una cosa del genere e ho sempre passato le matrici con le parentesi quadre però hai fatto un'ottima osservazione secondo me...

Per quello che mi ricordo le matrici sono "concettualmente" un array di array ma il compilatore fa delle ottimizzazioni per memorizzarle in ordine sequenziale. Quindi non escludo che tu abbia ragione però ti consiglio di non complicarti troppo le cose( l'ho fatto tante volte anch'io prima di te) perchè credo che fare il doppio puntatore sia solo una complicazione aggiuntiva e non ne conosco gli effetti perchè non l'ho mai provatoe poi come ho gìà detto le matrici sono memorizzate cmq in sequenza e a livello di memoria vengono cmq indicizzate mediante un unico puntatore. Più di questo non so dirti mi spiace (non sto nemmeno in condizioni mentali di mettermi a fare ADS!). Può darsi che qualcun altro più fresco di ASD possa darti una mano ulteriore. Ciao :D
Fai ciò che vuoi : sarà tutta la Legge. Amore è la Legge, Amore sotto la Volontà.

#3
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:
oddio... ma si pazz :D

già ti dico che fare cose strane come puntatori a puntatori a puntatori a puntatori (...) è un casino da gestire. ma poi dato che la matrice è già di per sè un puntatore che senso ha? o_O

Comunque, se proprio lo vuoi fare, supponendo di fare una matrice di TInfo, un modo è creandoti un nuovo tipo (e chiamarlo, chessò, Vettore) usando i costrutti STRUCT e TYPEDEF che contiene un puntatore al dato, quindi *TInfo (chiamandolo magari "elemento").

Alle funzioni passi un puntatore a Vettore, quindi un *Vettore (che puoi anche chiamare Matrice usando la TYPEDEF). Per accedere ad ogni elemento della matrice farai qualcosa del tipo Matrice[i]->elemento[j] (o almeno credo :D )
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#4
Marco De Rosa

Marco De Rosa

    Advanced Member

  • Utente
  • StellaStellaStella
  • 854 Messaggi:
Eh si diciamo che le mie a volte sono idee che lasciano il tempo che trovano......ma era solo una curiosità per approfondire la lezione sui puntatori.....pensavo ci fosse un modo più facile per farlo ma alla fine ero io che mi stavo complicando la vita........cmq ho trovato questo documento :

>Salve a tutti. Spesso uso l'aritmetica dei puntatori per accedere ad
>elementi di vettori. E' possibile farlo anche con matrici tipo a[5][5]?

T a[m][n];

significa un array di m array di n elementi di tipo T. In C (e C++) un
array decade, a meno di condizioni eccezionali, in puntatore al suo
primo elemento. Quindi scrivere: int a[5] e poi usare *(a+2) significa
far decadere 'a' al puntatore al suo primo elemento (quindi il
puntatore è di tipo int*) e incrementare l'indirizzo ottenuto di
2*sizeof(int) byte per raggiungere l'indirizzo del terzo elemento. Il
tuo 'a' è un array di 5 array di 5 elementi di tipo T (non l'hai
specificato), quindi se chiami S il tipo "array di 5 elementi di tipo
T", ottieni che 'a' è:

S a[5];

ora, scrivere *(a+2) significa far decadere 'a' al puntatore al suo
primo elemento (quindi il puntatore è di tipo S*) e incrementare
l'indirizzo ottenuto di 2*sizeof(S) byte per raggiungere l'indirizzo
del terzo elemento. Quello che ottieni è un elemento di tipo S, cioè a
sua volta un array. Essendo l'elemento un array di 5 elementi di tipo
T puoi riapplicare il ragionamento:

*(*(a+2)+3)

Fai cioè decadere il nuovo array *(a+2) in puntatore al suo primo
elemento di tipo T, quindi, incrementando l'indirizzo ottenuto di
3*sizeof(T) byte, raggiungi la posizione del quarto elemento di tipo
T.


Adesso non sò se centra o non centra e nn vi voglio neanche far perdere tempo.....quindi dategli una rapida lettura e se vi sembra che qualcosa mi possa aiutare fatemelo sapere....io ci capisco ben poco....visto che abbiamo iniziato a parlare dei puntatori solo oggi..... :D :D

#5
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:
a prima occhiata direi che non c'azzecca nulla, fa solo ragionamenti su cosa succede se fai alcune operazioni "strane" sugli array
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#6
ricky

ricky

    Advanced Member

  • Utente
  • StellaStellaStella
  • 63 Messaggi:

Quando l'elenco è composto da più di una persona......dopo che invoco le "free" alla fine.....e provo a ristampare l'elenco di persone non risultano deallocati i cognomi (dovrebbe darmi lettere strane e invece mi stampa i rispettivi cognomi delle persone nell'elenco).....

Io penso che il funzionamento di malloc sia diverso rispetto a quello che ci ha descritto Vento che lunedì se ricordo bene ha detto "se uso un puntatore all'indirizzo X senza inizializzarlo, ed eseguo il programma più volte, il suo valore stampato cambia sempre a caso", ma penso che come disse una volta Percannella, quando uno dealloca una certa area di memoria, non è che viene distrutto il dato e riscritto con un valore casuale, ma viene solamente "liberato" in modo che il sistema operativo può lasciarlo disponibile agli altri programmi, senza tenerlo più impegnato, quindi il dato rimane lì bello bello fino a quando quell'area di memoria non viene sovrascritta, o fino a quando spengo il pc e quindi la RAM diventa nuovamente caotica. Un pò come quando uno cancella un file dall'HD: se non sono stati riscritti i cluster precedentemente dedicati, i file sono lì e possono essere recuperati con software ad hoc.

#7
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:
la frase "se uso un puntatore all'indirizzo X senza inizializzarlo, ed eseguo il programma più volte, il suo valore stampato cambia sempre a caso" probabilmente si riferiva al fatto che se il puntatore all'indirizzo X non è inizializzato molto probabilmente a quell'indirizzo ci saranno "schifezze" in memoria, probabilmente dati lasciati da vecchi programmi eseguiti o semplicemente sequenze casuali di bit ancora non inizializzati perchè quell'area di memoria ancora deve essere usata da quando hai acceso il computer! E il fatto che il contenuto "cambia sempre a caso" ad ogni esecuzione è perchè ogni volta che lanci un programma viene allocata una diversa area di memoria riservata al processo...
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#8
Marco De Rosa

Marco De Rosa

    Advanced Member

  • Utente
  • StellaStellaStella
  • 854 Messaggi:
Apparte l'errore assurdo che ho fatto andando a mettere il sizeof non vicino a tipo.......

L'allocazione dinamica così come l'ho fatta va bene anche se mi stampa i dati dell'elenco di persone dopo che ho deallocato la memoria??
Se alloco i dati dinamicamente e il programma parte e fa quello che deve fare ,questa è condizione sufficiente che l'allocazione sia stata fatta bene??

Lo chiedo perchè il programma parte....e fa quello che deve fare....ma non sono sicuro che l'allocazione dinamica sia stata fatta bene....

#9
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:
A una prima occhiata, apparte l'errore che hai già segnalato, il codice mi sembra ok;

La deallocazione è incompleta: dopo aver deallocato le stringhe nome e cognome, devi anche deallocare la persona stessa con
free(p)
L'allocazione è ok. Cmq nn dovresti mai utilizzare dati che hai già deallocato!

Ti posto un vecchio esercizio fatto da me
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#10
Marco De Rosa

Marco De Rosa

    Advanced Member

  • Utente
  • StellaStellaStella
  • 854 Messaggi:

non dovresti mai usare dati che hai deallocato.

Lo sò enn li userò mai,la mia era giusto una stampa per vedere cosa succedeva dopo aver deallocato la memoria.....

Però ho un dubbio che mi porto da oggi pomeriggio.....

Io chiedo il riempimento dell'elenco nel main....e dopo vado ad allocare lo spazio dell'elenco con la malloc
elenco = ecc.......
In questo momento sto allocando lo spazio per (riemp*sizeof(persona)) byte........
Ma come fà ad allocare questo spazio se io conoscerò la dimensione di ogni persona soltanto dopo??.....cioè quando andrò a leggere i dati di ogni persona da tastiera??

#11
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:
Invece la dimensione di ogni persona è conosciuta a priori ed è data dalla somma delle dimensioni di char* nome, char* cognome e della data, che sono tutti elementi di dimensioni fisse. A questo punto potresti dire: "si ma io non conosco a priori di quanti caratteri sono formate le stringhe!" però queste 2 stringhe altro non sono a loro volta che dei puntatori, cioè dei semplici interi senza segno e quindi anch'essi a lunghezza fissa.

Cmq prima di farti troppe seghe mentali secondo me dovresti aspettare le prossime lezioni dove i puntatori verranno approfonditi meglio :D

EDIT: ho modificato il post precedente, rileggilo
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#12
ricky

ricky

    Advanced Member

  • Utente
  • StellaStellaStella
  • 63 Messaggi:

la frase "se uso un puntatore all'indirizzo X senza inizializzarlo, ed eseguo il programma più volte, il suo valore stampato cambia sempre a caso" probabilmente si riferiva al fatto che se il puntatore all'indirizzo X non è inizializzato molto probabilmente a quell'indirizzo ci saranno "schifezze" in memoria, probabilmente dati lasciati da vecchi programmi eseguiti o semplicemente sequenze casuali di bit ancora non inizializzati perchè quell'area di memoria ancora deve essere usata da quando hai acceso il computer! E il fatto che il contenuto "cambia sempre a caso" ad ogni esecuzione è perchè ogni volta che lanci un programma viene allocata una diversa area di memoria riservata al processo...

Hai ragione, non ci avevo pensato.

#13
Marco De Rosa

Marco De Rosa

    Advanced Member

  • Utente
  • StellaStellaStella
  • 854 Messaggi:

Cmq prima di farti troppe seghe mentali secondo me dovresti aspettare le prossime lezioni dove i puntatori verranno approfonditi meglio


E purtroppo mi devo preoccupare adesso perchè mercoledì ci stà la prima prova del contest e penso che i puntatori (come sempre dall'altro ieri quando sono stati spiegati la prima volta) la faranno da padrone......

Cmq grazie dell'esercizio....credo di aver capito dove sbagliavo....credo......confondevo l'indirizzo dell'area di memoria (che è un intero ed è quello che viene attribbuito ai puntatori a char *nome e *cognome) con il contenuto dell'area di memoria che saranno tot byte a seconda di quanto saranno grandi le stringhe......

Ho capito bene??

#14
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:
esatto... e forse questo già l'hai afferrato ma cmq lo dico: all'interno dell'area di memoria che allochi per l'elenco ci trovi soltanto le date (che sono allocate dinamicamente, e non staticamente come hai scritto tra i commenti del tuo programma) e i puntatori alle stringhe, mentre invece le stringhe stesse si trovano in altre aree di memoria che vai cmq ad allocare dinamicamente in area heap.

nel tuo programma le uniche cose che vengono allocate staticamente sono riemp e il puntatore all'elenco.
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#15
Marco De Rosa

Marco De Rosa

    Advanced Member

  • Utente
  • StellaStellaStella
  • 854 Messaggi:
Ok ....l'ultima cosa.....se nell'area di memoria che alloco per elenco....ci trovo anche le date......perchè quando faccio free(elenco)....le date non si deallocano e mi vengono stampate di nuovo??
Vale il ragionamento di prima oppure dovrei deallocare ogni persona prima di deallocare l'elenco??

#16
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:
Devi deallocare ogni persona prima di deallocare tutto l'elenco ma cmq dopo la deallocazione i dati rimangono in memoria a meno che non vengano sovrascritti.
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#17
ricky

ricky

    Advanced Member

  • Utente
  • StellaStellaStella
  • 63 Messaggi:
Mi permetto un appunto che ho notato :book:

sostituisci questo pezzo di codice quando accedi ad una persona

(elenco+i)
con questo che è più decente, e rende meglio l'idea
elenco[i]
come se fosse un vettore allocato staticamente (funziona con qualsiasi puntatore)

elenco[i] da errore, perchè la leggi_persona cerca un indirizzo. In parole povere
*(elenco+i)=elenco[i]
(elenco+i)=&elenco[i]
:dance:

#18
marco89thebest

marco89thebest

    Newbie

  • Utente
  • StellaStellaStella
  • 358 Messaggi:
Nella mia ignoranza volevo aggiungere una cosa...
1) Non ho letto i post precedenti per la comprensibile lunghezza
2) guardando il codice com'è stato postato, mi dava un errore nella stampa dell'elenco...
Se ci fate caso, prima cancella la memoria e poi la stampa... Credo sia quello il motivo per cui da errore nella visualizzazione_elenco...

Probabile che ve ne siate già accorti... kmq non credo che l'errore sia nell'(elenco+i)...

Provando a sostituire i codici che ricky ha consigliato non funziona...

Ovviamente posso essermi sbagliato... :ciao:


Ho sbagliato... Ho letto velocemente il prog...
"Io so di non sapere". Socrate

Sogna come se non dovessi morire mai, vivi come se dovessi morire oggi.

Immagine inviata

#19
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:
ah, ovviamente ricky ha ragione... il fatto è che il C me lo sono scordato e quindi anche il fatto degli * e & (ormai mi sono abituato a trattare tutto per riferimento, e non per valore)

per quanto riguarda il fatto che prima si dealloca e poi si legge, non è un errore ma una cosa fatta apposta
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#20
johnny88

johnny88

    Newbie

  • Utente
  • StellaStellaStella
  • 1109 Messaggi:
Ragazzi kmqmi sa ke vi state confondendo un po le idee. Una matrice nn è un puntatore doppio. Se dichiaro una matrice m[], m indica l'indirizzo di base della matrice. Facendo m[i] [j]si aggiunge all'indirizzo base il numero di bit tale ke ci spostiamo su righe e colonne diverse della matrice. La matrice quindi segue l'aritmetica dei puntatori, e in memoria tutti gli elementi della matrice sono allocati comunque in maniera sequenziale.
"Il vero aspetto di tutti i fenomeni può essere compreso e condiviso solo tra Budda. Questa realtà consiste di: aspetto, natura, entità, potere, azione, causa interna, relazione, effetto latente, retribuzione e della loro coerenza dall'inizio alla fine"




Leggono questa discussione 0 utenti

0 utenti, 0 ospiti, 0 utenti anonimi