Passa l’argomento puntatore, passa per valore in C ++?

Passa l’argomento puntatore, passa per valore in C ++? Dal momento che vedo che qualsiasi modifica al puntatore in quanto tale non viene riflessa al di fuori del metodo. Le modifiche che faccio dereferenziando il puntatore si riflettono però.

In tal caso, è accettabile / procedura standard utilizzare il puntatore al puntatore come argomento di una funzione per modificare il valore del puntatore come tale all’interno di una funzione?

Sì ad entrambi.

I puntatori vengono passati per valore come qualsiasi altra cosa. Ciò significa che il contenuto della variabile puntatore (l’indirizzo dell’object puntato a) viene copiato. Ciò significa che se si modifica il valore del puntatore nel corpo della funzione, tale modifica non verrà riflessa nel puntatore esterno che continuerà a puntare al vecchio object. Ma puoi cambiare il valore dell’object puntato.

Se si desidera riflettere le modifiche apportate al puntatore al puntatore esterno (fare riferimento a qualcos’altro), sono necessari due livelli di riferimento indiretto (puntatore al puntatore). Quando si chiamano le funzioni è fatto mettendo un & prima del nome del puntatore. È il modo standard C di fare le cose.

Quando si usa il C ++, l’uso dei riferimenti è preferito al puntatore (d’ora in avanti anche al puntatore al puntatore).

Per il perché i riferimenti dovrebbero essere preferiti ai puntatori, ci sono diversi motivi:

  • i riferimenti introducono meno rumore sintattico dei puntatori nel corpo della funzione
  • i riferimenti mantengono più informazioni dei puntatori, che possono essere utili per il compilatore

Gli svantaggi dei riferimenti sono principalmente:

  • essi infrangono la semplice regola del valore pass-by di C, cosa rende meno ovvia la comprensione del comportamento di una funzione rispetto ai parametri (saranno cambiati?). Hai anche bisogno di un prototipo di funzione per essere sicuro. Ma questo non è veramente peggio dei multipli livelli di puntatore necessari quando si usa C.
  • non sono supportati da C, può essere un problema quando si scrive codice che dovrebbe funzionare con entrambi i programmi C e C ++ (ma non è il caso più comune).

Nel caso specifico del puntatore al puntatore, la differenza è principalmente la semplicità, ma usando il riferimento può anche essere facile rimuovere entrambi i livelli di puntatori e passare solo un riferimento invece di un puntatore al puntatore.

Capisco la confusione qui. I concetti di “passare per valore” e “passare per riferimento” non sono così chiari anche se sembrano essere così. Ricorda che il computer non conosce questi concetti e non si comporta in base ad esso. Il computer non conosce i tipi. Quindi non fa una distinzione di indicatori e valori. Lasciatemi provare a spiegare per esempio:

 void func1(int x) { x = 5; } void func2(int *x) { int a; x = &a; } 

L’operazione è la stessa per la macchina in entrambe le funzioni: ottiene l’argomento e lo modifica. Nota che, in seconda funzione, non modifica * x, modifica x .

Ora se chiamiamo queste funzioni,

 int y = 10; func1(y); //value of y does not change func2(&y); //value of &y does not change, but the value of the address which y points may change. 

Preferisco dire che, in sostanza, ogni chiamata di funzione è “chiamata per valore” . Ma nel caso di un tipo di puntatore, abbiamo un modo per cambiare il contenuto di un altro indirizzo in memoria.

Se avessimo scritto func2 come

 void func2(int *x) { *x = 5; } 

Quindi, questo sarebbe un vero caso di “chiamata per riferimento”.

O un puntatore a un puntatore o un riferimento a un puntatore, è ciò che usereste se si volesse modificare potenzialmente il puntatore stesso. Alla tua domanda iniziale, tecnicamente, sì, tutti i parametri sono passati per valore.

Sì, lo è, come lo è in C.

In tal caso, è accettabile / procedura standard utilizzare il puntatore al puntatore come argomento di una funzione per modificare il valore del puntatore come tale all’interno di una funzione?

In quale caso? Cosa vuoi? Puoi utilizzare riferimenti reali con il modificatore & .

 void func(type &ref);