puntatore costante contro puntatore su un valore costante

Qual è la differenza tra le seguenti dichiarazioni?

char * const a; const char * a; 

Per capire la differenza ho scritto questo piccolo programma:

 #include  #include  int main (int argc, char **argv) { char a = 'x'; char b = 'y'; char * const pc1 = &a; const char * pc2 = &a; printf ("Before\n"); printf ("pc1=%p\n", pc1); printf ("*pc1=%c\n", *pc1); printf ("pc2=%p\n", pc2); printf ("*pc2=%c\n", *pc2); *pc1 = b; /* pc1 = &b; */ /* *pc2 = b; */ pc2 = &b; printf ("\n\n"); printf ("After\n"); printf ("pc1=%p\n", pc1); printf ("*pc1=%c\n", *pc1); printf ("pc2=%p\n", pc2); printf ("*pc2=%c\n", *pc2); return EXIT_SUCCESS; } 

Ho compilato il programma (con gcc 3.4) e l’ho eseguito. L’output evidenzia la differenza piuttosto bene:

 Before pc1=ffbfd7e7 *pc1=x pc2=ffbfd7e7 *pc2=x After pc1=ffbfd7e7 *pc1=y pc2=ffbfd7e6 *pc2=x 

Tuttavia, ho dovuto scrivere il piccolo programma per ottenere la risposta. Nel caso in cui fossi lontano dalla macchina (ad esempio per un’intervista), non sarei in grado di rispondere alla domanda.

Qualcuno può spiegare, commentando l’esempio precedente, come funziona la parola chiave const ?

 char * const a; 

significa che il puntatore è costante e immutabile ma i dati puntati non lo sono.
Potresti usare const_cast (in C ++) o cast in stile c per eliminare la costanza in questo caso in quanto i dati stessi non sono costanti.

 const char * a; 

significa che i dati puntati non possono essere scritti usando il puntatore a. L’utilizzo di un const_cast (C ++) o di un cast di tipo c per eliminare la costanza in questo caso causa un comportamento indefinito .

Per analizzare tipi complicati, inizi dalla variabile, vai a sinistra e spirale verso l’esterno. Se non ci sono array o funzioni di cui preoccuparsi (perché questi siedono a destra del nome della variabile) questo diventa un caso di lettura da destra a sinistra.

Quindi con char *const a; hai a , che è un puntatore const ( * ) per un char . In altre parole, puoi cambiare il carattere a cui punta il puntamento, ma non puoi fare a punto in qualcosa di diverso.

Al contrario con const char* b; hai b , che è un puntatore ( * ) per un char che è const . Puoi fare un punto b con qualsiasi carattere che preferisci, ma non puoi cambiare il valore di quel carattere usando *b = ...; .

Ovviamente puoi anche avere entrambi i sapori di costanza in una volta: const char *const c; .

 char * const a; 

*a è scrivibile, ma a non lo è; in altre parole, è ansible modificare il valore indicato da a , ma non è ansible modificarne a . a è un puntatore costante al char .

 const char * a; 

a è scrivibile, ma *a non lo è; in altre parole, è ansible modificare a (puntandolo in una nuova posizione), ma non è ansible modificare il valore indicato da a .

Si noti che questo è identico a

 char const * a; 

In questo caso, a è un puntatore a un const char .

Ora che conosci la differenza tra char * const a e const char * a . Molte volte ci confondiamo se è un puntatore o puntatore costante a una variabile costante.

Come leggerlo? Segui il semplice passaggio sottostante per identificare tra i due superiori.

Vediamo come leggere sotto la dichiarazione

 char * const a; 

leggi da destra a sinistra

Ora inizia con a ,

1. adiacente a a ci è const .

char * (const a) ;

—> Quindi a è una constant (????) .

2. Ora vai avanti, ottieni *

char (* (const a)) ;

—> Quindi a è un pointer constant a (????) .

3. Vai e c’è il char

(char (* (const a))) ;

—> a è un pointer constant alla variabile di character

 a is constant pointer to character variable. 

Non è facile da leggere?

Analogamente per la seconda dichiarazione

 const char * a; 

Ora di nuovo inizio con a ,

1. Adiacente ad a c’è *

—> Quindi a è un pointer a (????)

2. Ora c’è char

—> quindi a è il character pointer ,

Beh, questo non ha senso !!! Quindi pointer casuale e character

—> quindi a è il pointer character a (?????)

3. Ora sei constant

—> quindi a è il pointer character alla variabile constant

Ma anche se puoi capire che cosa significa la dichiarazione, lascia che suoni più sensato.

 a is pointer to constant character variable 

Il modo più semplice per capire la differenza è pensare alle diverse possibilità. Ci sono due oggetti da considerare, il puntatore e l’object puntato (in questo caso ‘a’ è il nome del puntatore, l’object a cui si fa riferimento è senza nome, di tipo char). Le possibilità sono:

  1. niente è costante
  2. il puntatore è const
  3. l’object puntato è const
  4. sia il puntatore che l’object puntato sono const.

Queste diverse possibilità possono essere espresse in C come segue:

  1. char * a;
  2. char * const a;
  3. const char * a;
  4. const char * const a;

Spero che questo illustri le possibili differenze

Il primo è un puntatore costante a un carattere e il secondo è un puntatore a un carattere costante. Non hai toccato tutti i casi nel tuo codice:

 char * const pc1 = &a; /* You can't make pc1 point to anything else */ const char * pc2 = &a; /* You can't dereference pc2 to write. */ *pc1 = 'c' /* Legal. */ *pc2 = 'c' /* Illegal. */ pc1 = &b; /* Illegal, pc1 is a constant pointer. */ pc2 = &b; /* Legal, pc2 itself is not constant. */ 

Lo spiegherò prima verbalmente e poi con un esempio:

Un object puntatore può essere dichiarato come puntatore const o puntatore a un object const (o entrambi):

Un puntatore const non può essere riassegnato per puntare a un object diverso da quello a cui è inizialmente assegnato, ma può essere utilizzato per modificare l’object a cui punta (chiamato “punta”).
Le variabili di riferimento sono quindi una syntax alternativa per i costanti.

Un puntatore a un object const , d’altra parte, può essere riassegnato per puntare a un altro object dello stesso tipo o di un tipo convertibile, ma non può essere utilizzato per modificare alcun object.

Un puntatore const a un object const può anche essere dichiarato e non può essere utilizzato per modificare il punto di punta né essere riassegnato per puntare a un altro object.

Esempio:

 void Foo( int * ptr, int const * ptrToConst, int * const constPtr, int const * const constPtrToConst ) { *ptr = 0; // OK: modifies the "pointee" data ptr = 0; // OK: modifies the pointer *ptrToConst = 0; // Error! Cannot modify the "pointee" data ptrToConst = 0; // OK: modifies the pointer *constPtr = 0; // OK: modifies the "pointee" data constPtr = 0; // Error! Cannot modify the pointer *constPtrToConst = 0; // Error! Cannot modify the "pointee" data constPtrToConst = 0; // Error! Cannot modify the pointer } 

Felice di aiutare! In bocca al lupo!

Sopra sono ottime risposte. Ecco un modo semplice per ricordare questo:

a è un puntatore

* a è il valore

Ora se dici “const a” allora il puntatore è const. (es. char * const a;)

Se dici “const * a”, allora il valore è const. (cioè const char * a;)

Puoi usare l’utilità cdecl o le sue versioni online, come https://cdecl.org/

Per esempio:

void (* x)(int (*[])()); è una declare x as pointer to function (array of pointer to function returning int) returning void

Cercando di rispondere in modo semplice:

 char * const a; => a is (const) constant (*) pointer of type char {L < - R}. =>( Constant Pointer ) const char * a; => a is (*) pointer to char constant {L < - R}. =>( Pointer to Constant) 

Puntatore costante:

il puntatore è costante !! cioè, l’indirizzo che è in possesso non può essere modificato. Sarà memorizzato nella memoria di sola lettura.

Proviamo a cambiare l’indirizzo del puntatore per capire meglio:

 char * const a = &b; char c; a = &c; // illegal , you can't change the address. `a` is const at L-value, so can't change. `a` is read-only variable. 

Significa che una volta puntatore costante punta a qualcosa è per sempre.

puntatore a punti solo b .

Tuttavia è ansible modificare il valore di b eg:

 char b='a'; char * const a =&b; printf("\n print a : [%c]\n",*a); *a = 'c'; printf("\n now print a : [%c]\n",*a); 

Puntatore a Costante:

Il valore indicato dal puntatore non può essere modificato.

 const char *a; char b = 'b'; const char * a =&b; char c; a=&c; //legal *a = 'c'; // illegal , *a is pointer to constant can't change!. 
 const char * a; 

Questo indica il puntatore al carattere costante. Per es.

 char b='s'; const char *a = &b; 

Qui a punto a un carattere costante (‘s’, in questo caso). Non puoi usare a per modificare quel valore.Ma questa dichiarazione non significa che il valore a cui punta è davvero una costante , significa solo il valore è una costante in quanto è interessato. È ansible modificare il valore di b direttamente modificando il valore di b , ma non è ansible modificare il valore indirettamente tramite il puntatore a.

*a='t'; //INVALID b='t' ; //VALID

 char * const a=&b 

Questo indica un puntatore costante al char. Limita a puntare solo a b ma ti permette di modificare il valore di b .

Spero che sia d’aiuto!!! 🙂