|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Aug 2009
Messaggi: 287
|
[C] dubbio su puntatori/doppi puntatori
Ciao a tutti, ho un dubbio sull'utilizzo dei doppi puntatori.
So che sono dei puntatori a puntatori e possono essere utilizzati per modificare dei puntatori in una void e andrebbero usati in procedure intestate così: void modificaPunt (**puntatore) e richiamando la procedura in questo modo: modificaPunt(&(*punt)) Giusto? Quello che mi chiedo è: non potrei creare una void che per parametra accetta dei semplici puntatori e passargli l'indrizzo del puntatore? Ad esempio: modificaPunt(&(punt)) Non otterrei lo stesso risultato di prima? |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2006
Città: milano
Messaggi: 1439
|
Certo, se punt è un puntatore sì. Infatti, non credo che esista un solo modo di scrivere quei prototipi e quelle chiamate
|
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Aug 2009
Messaggi: 287
|
quindi nel caso di una funzone che prende in ingresso due liste e le modifica entrambe, l'uso dei doppi puntatori è superfluo, giusto?
Basta che passo l'indirizzo dei puntatori delle liste così: modificaPunt(&punt1,&punt2) dove punt1 e punt2 sono dei puntatori ?? |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Oct 2006
Città: milano
Messaggi: 1439
|
Secondo me è troppo vago. Dipende da com'è implementata.
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
le varie strutture dati sono semplici astrazioni e in realtà sono combinazioni di operatori e dati usati con una certa logica e sintassi.
Una struttura dati come gli array multidimensionali ( matrici ) ovvero: Codice:
char matrix[N][M] tratto una riga come singolo puntatore Codice:
strcpy(matrix[5],"Ciao Ciao"); l'esempio completo è Codice:
#include <stdio.h>
#include <string.h>
#define N 10
void azzeraMatrice(char myMatrix[][N]);
void printMatrice(char myMatrix[][N]);
void main(){
char matrix[N][N];
azzeraMatrice(matrix);
strcpy(matrix[5],"Ciao Ciao");
printMatrice(matrix);
}
void azzeraMatrice(char myMatrix[][N]){
int i=0,j=0;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
myMatrix[i][j]=0;
}
}
}
void printMatrice(char myMatrix[][N]){
int i=0,j=0;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf("%c",myMatrix[i][j]);
}
printf("\n");
}
}
|
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Aug 2009
Messaggi: 287
|
provo a spiegarmi meglio:
Supponiamo di avere due liste doppiamente puntate non circolari create utilizzando questa struttura: struct el { struct el *prev; int num; struct el *next; } e di avere le due liste struct el L1, L2; Volendo implementare una void ricorsiva che le modifica entrambe (magari toglie dei numeri da una per metterli nell'altra), devo utilizzare i doppi puntatori oppure mi basta chiamare la void passando &L1, &L2 (ovvero gli indirizzi dei puntatori) ?? |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
Quote:
un puntatore a puntatore coinvolge 2 puntatori, il primo puntatore conserva l'indirizzo del secondo che a sua volta punta all'indirizzo della variabile referenziata. quindi: - se passi l'indirizzo di un puntatore a puntatore ti basta dereferenziarlo 2 volte per ottenere il valore voluto - se dereferenzi 1 sola volta un puntatore a puntatore ottieni l'indirizzo della variabile che contiene il valore voluto l'indirizzo di un puntatore è l'equivalente concettuale di un puntatore a puntatore, l'operatore & restituisce un puntatore che contiene l'indirizzo della variabile che sta alla sua destra, quindi nel caso ci fosse un puntatore l'operatore & restituisce un puntatore a puntatore. la tipologia di puntatore dipende anche dalla definizione che da il compilatore all'operatore & ma tutto sommato & rimane un generatore di puntatori considerando come indirizzo conservato dal puntatore l'indirizzo di ciò che è presente alla sua destra. |
|
|
|
|
|
|
#8 | |
|
Member
Iscritto dal: Aug 2009
Messaggi: 287
|
Quote:
In pratica (stando all'esempio) l'intestazione della void sarà : void modifcaliste(struc el **L1, struct el**L2) mentre per chiamarla dovrò fare così: modificaliste(&*L1,&*L2) Giusto? |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2007
Messaggi: 2267
|
Sicuro servano i puntatori a puntatori?
Codice:
void modificaliste(el* L1, el* L2){...}
__________________
Concluso con:... |
|
|
|
|
|
#10 |
|
Member
Iscritto dal: Aug 2009
Messaggi: 287
|
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jan 2007
Messaggi: 2267
|
Beh difficile dirti qualcosa senza maggiori spiegazioni su cosa vuoi fare.
Ad esempio se vuoi aggiungere alla lista L un elemento di valore x ponendolo come pos-esimo elemento, dovresti fare qualcosa del genere: Codice:
//L puntatore al primo elemento della lista (non circolare!)
void addElementToList(el* L, int x, int pos){
//cerchi la posizione nella lista...
el* node = L;
for(int i=0; i<pos; i++){
node = node->next;
}
//...crei l'elemento da aggiungere
el* nodeToAdd = new el(node,x,node->next);
//e lo aggiungi sistemando i puntatori dei nodi adiacenti
node->next->prev = nodetoAdd;
node->next = nodetoAdd;
}
__________________
Concluso con:... Ultima modifica di Floris : 22-09-2011 alle 05:16. |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Jan 2007
Messaggi: 2267
|
Rispondendo ad un altro thread mi sono accorto di una correzione da fare al codice che ti ho postato: infatti se l'elemento è da aggiungere in testa allora il puntatore alla testa della lista che avrai al di fuori della funzione non punterà più alla testa della lista ma al secondo elemento. Quindi la funzione dovrebbe ritornare il puntatore alla testa della lista (che potrebbe essere cambiato).
Alternativamente si può fare con i doppi puntatori modificando il puntatore (o meglio il r-value del puntatore) alla testa della lista passato alla funzione (come dicevi tu all'inizio del thread).
__________________
Concluso con:... Ultima modifica di Floris : 23-09-2011 alle 23:46. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 07:53.




















