PDA

Visualizza la versione completa : [C++] Chiarimenti su array e puntatori


PazEr
20-12-2013, 19:49
Salve a tutti, sono nuovo del forum! :cool:

Dopo aver passato un po' di tempo a cimentarmi col Python, ho deciso di imparare il C++.
Ho seguito la guida di questo sito, e ad ogni argomento ho svolto degli esercizi trovati in rete, insomma mi trovo bene. Andando avanti però, ho avuto dei dubbi specialmente sugli array e sui puntatori.
Ho capito abbastanza bene gli array e credo possano essere utili in vari modi ma non vedo la loro utilità se dichiarati come contenitori di caratteri. Non sarebbe meglio utilizzare il modulo string? Anche perché con gli array corri il rischio di definirne uno troppo grande oppure troppo piccolo... :dhò:
I puntatori invece, beh, non è che mi siano tanto chiari :confused:, ho provato anche a vedere su altre guide e persino sui vari manuali in pdf ma non sono spiegati molto bene (partendo dal fatto che ogni paragrafo sui puntatori parte con "i puntatori sono l'argomento più difficile per un principiante etc. etc.").
Per quanto ho capito sono delle variabili (vero?) che puntano ad altre variabili copiandone il valore.
E detto così non è che sembrino poi così utili... :facepalm: C'è mica qualche buon'anima che può spiegarmeli in modo chiaro? Ringrazio anticipatamente! :D

Scara95
20-12-2013, 20:00
Compra un libro ^_^

Il modo più chiaro per capire i puntatori a mio parere è quello di pensarli come un indirizzo (che poi è quello che sono). Quando usi un puntatore non passi in giro il valore, ma il suo indirizzo e, quando deferenzi (*ptr) un puntatore non fai altro che "andare" a quell'indirizzo. Questo a varie conseguenze ad esempio che le modifiche vengono apportate sempre "nello stesso posto".

Se ora ti possono sembrare inutili quando comincerai a fare un po' di strutture dati ti renderai conto della loro utilità.

PazEr
21-12-2013, 16:28
Grazie della risposta, è buono come libro Pensare in C++ di Bruce Eckel? Ho visto delle buone recensioni...

MItaly
21-12-2013, 17:56
Per quanto ho capito sono delle variabili (vero?) che puntano ad altre variabili copiandone il valore.
E detto così non è che sembrino poi così utili...
Sono talmente utili che in Python e in praticamente ogni altro VHLL tutte le variabili di tipi non primitivi sono puntatori (ma con gestione automatica della memoria). :stordita:

PazEr
21-12-2013, 22:02
Niente da fare, in Pensare in C++ i puntatori sono spiegati malissimo, tra l'altro sono spiegati insieme al passaggio di valori per riferimento, il che fa in modo di non farmi capire neanche il secondo argomento :dhò:

Patrick Jane
22-12-2013, 00:09
Guarda in realtà sono molto semplici. Non farti spaventare dalle parole del libro...

Iniziamo con il passaggio per valore e riferimento.
Ogni variabile ha un indirizzo di memoria, visto che da qualche parte deve pur risiedere il valore. Quando tu chiami una funzione e come argomento passi una variabile, questa viene passata per valore. Questo significa che di fatto viene fatta una copia del tuo valore, ovvero del numero che contiene la variabile. Questo numero viene memorizzato nel parametro della tua funzione. Quindi:



void funzione(int n) {
n += 10;
}

int main() {
int numero = 100;
funzione(numero);
return 0;
}


viene copiato il valore di numero, quindi 100, e viene memorizzato in n. Questo che implica? Implica che la nostra funzione opera una modifica (somma il numero 10 ad n) alla variabile n. Ma come abbiamo detto ogni variabile ha un indirizzo di memoria. Quindi la situazione finale è:


numero = 100;
n = 110;


Detto usando altre parole: la funzione modifica la variabile n, ma la modifica non avviene anche alla variabile numero, in quanto hanno indirizzi di memoria diversi.

Il passaggio per riferimento invece significa passare il riferimento, ovvero l'indirizzo della variabile. Con gli array questo accade automaticamente, nel senso che sono appunto sempre passati per riferimento. Questo che significa, rispetto a quanto detto per il passaggio per valore? Significa che se noi passiamo per riferimento, la variabile numero, all'interno della funzione qualsiasi modifica viene fatta ad n, si riflette su numero. Questo perchè condividono lo stesso spazio in memoria!
Immagina le variabili come due scatole: nel primo caso ho la variabile numero con l'indirizzo (ne sparo uno, solo come esempio) 0xAAAAAA e quando la passo per valore copio il numero che contiene questo indirizzo, ovvero 100.
Nel secondo caso, non passo il numero 100, ma l'indirizzo 0xAAAAAA e di conseguenza n ora ha indirizzo 0xAAAAAA; ergo, non possono che puntare alla stessa cella della memoria.

Ma come si passa per riferimento una variabile? Usando i puntatori e l'operatore &. In pratica un puntatore contiene un indirizzo di memoria che può far riferimento ad un numero o un carattere (ma anche puntare ad una struct, ma le vedrai avanti; e ti chiariranno anche la necessità dei puntatori).
Quindi:


int numero = 100;
int *n = №


ora n punta alla stessa locazione di numero, e se la modifico vado a modificare per forza il valore di numero.



#include<iostream>

using namespace std;

void funzione(int n) {
n+=10;
}
void funzione(int *n) {
*n+=10;
}

int main() {
int numero = 100;
cout << "Valore di numero: "<<numero<<endl;
funzione(numero);
cout << "[passaggio di numero per valore.]\nValore di numero attuale: " << numero<< endl;
funzione(&numero);
cout << "\nValore numero dopo passaggio per riferimento: "<<numero<<endl;

return 0;
}


Output:


Valore di numero: 100
[passaggio di numero per valore.]
Valore di numero attuale: 100

Valore numero dopo passaggio per riferimento: 110


Come vedi non è complicato. ;)

PazEr
22-12-2013, 16:32
Grazie infinite!
Sei stato molto più chiaro tu che le 10 e più pagine del libro.
Tutte le guide che ho letto spiegavano che il puntatore punta ad una variabile che a sua volta punta ad un indirizzo, ma in realtà sia la variabile che il puntatore puntano allo stesso indirizzo di memoria, quindi modificando il valore segnato nell'indirizzo esso si modifica per tutte le variabili che puntano ad esso.
Ancora grazie! :D

Patrick Jane
22-12-2013, 18:20
Prego, è un piacere essere d'aiuto! ;)

Loading