Qual è la differenza tra:
char * const
e
const char *
Qual è la differenza tra:
char * const
e
const char *
Risposte:
La differenza è che const char *
è un puntatore a const char
, mentre char * const
è un puntatore costante a char
.
Il primo, il valore indicato non può essere modificato, ma può essere il puntatore. Il secondo, il valore puntato può cambiare ma il puntatore non può (simile a un riferimento).
C'è anche un
const char * const
che è un puntatore costante a un carattere costante (quindi nulla può essere modificato).
Nota:
Le seguenti due forme sono equivalenti:
const char *
e
char const *
Il motivo esatto è descritto nello standard C ++, ma è importante notare ed evitare la confusione. Conosco diversi standard di codifica che preferiscono:
char const
al di sopra di
const char
(con o senza puntatore) in modo che il posizionamento const
dell'elemento sia lo stesso di un puntatore const
.
const int *foo,*bar;
che dichiarerebbe entrambi foo
e bar
di essere int const *
, ma int const *foo, *bar
dichiarerebbe foo
di essere un int const *
e bar
di essere int *
. Penso typedef int * intptr; const intptr foo,bar;
che dichiarerebbe entrambe le variabili int * const
; Non conosco alcun modo per utilizzare una dichiarazione combinata per creare due variabili di quel tipo senza un typedef.
I believe const int *foo,*bar; would declare both foo and bar to be int const *
: Sì. but int const *foo, *bar would declare foo to be a int const * and bar to be int *
: No! Sarebbe esattamente lo stesso del caso precedente. (Vedi ideone.com/RsaB7n dove ottieni lo stesso errore sia per foo che per bar). I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const
: Sì. I don't know any way to use a combined declaration to create two variables of that type without a typedef
: Beh, int *const foo, *const bar;
. Sintassi del dichiaratore C ...
int const *foo, *volatile bar
per bar
? Renderlo entrambi const
e volatile
? Separazione di I Miss Pascal pulita di nomi di variabili dichiarati e le loro tipologie (un puntatore a un array di puntatori a interi sarebbero var foo: ^Array[3..4] of ^Integer
.;. `Sarebbe alcuni divertenti cosa parentesi nidificato in C, credo
int const *foo, *volatile bar
" la parte del tipo è int const
(si ferma prima del *
) e i dichiaratori sono *foo
(l'espressione *foo
indicherà un int const
) e *volatile bar
; lettura da destra a sinistra (buona regola per i qualificatori cv ), foo
è un puntatore a un const int ed bar
è un puntatore volatile a un const int (il puntatore stesso è volatile, l'int puntato è [accessibile come] const).
[3..4]
sintassi, quindi cerchiamo di prendere un array di 10 elementi): int *(*foo)[10];
. Riflette il suo (futuro) uso come espressione: *(*foo)[i]
(con i
un numero intero nell'intervallo [0, 10)
cioè [0, 9]
) farà prima il dereference foo
per arrivare all'array, quindi accederà all'elemento in index i
(perché postfix si []
lega più stretto del prefisso *
), quindi dereference questo elemento, infine cedere un int
(vedi ideone.com/jgjIjR ). Ma typedef
rende più semplice (vedi ideone.com/O3wb7d ).
Per evitare confusione, aggiungere sempre il qualificatore const.
int * mutable_pointer_to_mutable_int;
int const * mutable_pointer_to_constant_int;
int *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;
p
non riguarda il tipo: (const int *const)
. Nel bene o nel male (peggio se me lo chiedi) il qualificatore const, sia in C che in C ++, è pensato per essere postfix: cf const membro function void foo(int a) const;
. La possibilità di dichiarare const int
è l'eccezione piuttosto che la regola.
const
modifica sempre la cosa che le precede (alla sua sinistra), TRANNE quando è la prima cosa in una dichiarazione di tipo, dove modifica la cosa che la segue (alla sua destra).
Quindi questi due sono gli stessi:
int const *i1;
const int *i2;
definiscono i puntatori a const int
. Puoi cambiare dove i1
e i2
punti, ma non puoi cambiare il valore a cui puntano.
Questo:
int *const i3 = (int*) 0x12345678;
definisce un const
puntatore a un numero intero e lo inizializza in modo che punti nella posizione di memoria 12345678. È possibile modificare il int
valore all'indirizzo 12345678, ma non è possibile modificare l'indirizzo a cui i3
punta.
const * char
è un codice C non valido ed è insignificante. Forse intendevi chiedere la differenza tra a const char *
e a char const *
, o forse la differenza tra a const char *
e achar * const
?
const char*
è un puntatore a un carattere costante
char* const
è un puntatore costante a un personaggio
const char* const
è un puntatore costante a un carattere costante
Regola empirica: leggi la definizione da destra a sinistra!
const int *foo;
Significa " foo
punti ( *
) a un int
che non può cambiare ( const
)".
Per il programmatore questo significa "Non cambierò il valore di ciò che foo
indica".
*foo = 123;
o foo[0] = 123;
sarebbe non valido.foo = &bar;
È permesso.int *const foo;
Significa " foo
impossibile cambiare ( const
) e punta ( *
) a un int
".
Per il programmatore questo significa "Non cambierò l' indirizzo di memoria a cui si foo
riferisce".
*foo = 123;
o foo[0] = 123;
è permesso.foo = &bar;
sarebbe invalido.const int *const foo;
Significa " foo
impossibile cambiare ( const
) e punta ( *
) a un int
che non può cambiare ( const
)".
Per il programmatore questo significa "Non cambierò il valore di ciò a cui foo
punta, né cambierò l' indirizzo a cui si foo
riferisce".
*foo = 123;
o foo[0] = 123;
sarebbe non valido.foo = &bar;
sarebbe invalido.const char * x Qui X è sostanzialmente un puntatore a caratteri che punta a un valore costante
char * const x si riferisce al puntatore di carattere che è costante, ma la posizione a cui punta può essere modificata.
const char * const x è una combinazione di 1 e 2, significa che è un puntatore a carattere costante che punta a un valore costante.
const * char x provocherà un errore del compilatore. non può essere dichiarato.
char const * x è uguale al punto 1.
la regola empirica è se const è con il nome var quindi il puntatore sarà costante ma la posizione di puntamento può essere cambiata , altrimenti il puntatore punterà a una posizione costante e il puntatore può puntare su un'altra posizione ma il contenuto della posizione di puntamento non può essere cambiato .
Molte risposte forniscono tecniche specifiche, regola dei pollici ecc. Per comprendere questa particolare istanza di dichiarazione variabile. Ma esiste una tecnica generica per comprendere qualsiasi dichiarazione:
Regola in senso orario / a spirale
UN)
const char *a;
Secondo la regola in senso orario / spirale a
è puntatore a carattere che è costante. Ciò significa che il carattere è costante ma il puntatore può cambiare. cioè a = "other string";
va bene ma a[2] = 'c';
non riuscirà a compilare
B)
char * const a;
Secondo la regola, a
è puntatore const a un personaggio. cioè puoi farlo a[2] = 'c';
ma non puoi farloa = "other string";
Suppongo che intendi const char * e char * const.
Il primo, const char *, è un puntatore a un carattere costante. Il puntatore stesso è modificabile.
Il secondo, char * const è un puntatore costante a un carattere. Il puntatore non può cambiare, il carattere a cui punta può.
E poi c'è const char * const in cui il puntatore e il carattere non possono cambiare.
Ecco una spiegazione dettagliata con il codice
/*const char * p;
char * const p;
const char * const p;*/ // these are the three conditions,
// const char *p;const char * const p; pointer value cannot be changed
// char * const p; pointer address cannot be changed
// const char * const p; both cannot be changed.
#include<stdio.h>
/*int main()
{
const char * p; // value cannot be changed
char z;
//*p = 'c'; // this will not work
p = &z;
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
char * const p; // address cannot be changed
char z;
*p = 'c';
//p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
const char * const p; // both address and value cannot be changed
char z;
*p = 'c'; // this will not work
p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
// Some more complex constant variable/pointer declaration.
// Observing cases when we get error and warning would help
// understanding it better.
int main(void)
{
char ca1[10]= "aaaa"; // char array 1
char ca2[10]= "bbbb"; // char array 2
char *pca1= ca1;
char *pca2= ca2;
char const *ccs= pca1;
char * const csc= pca2;
ccs[1]='m'; // Bad - error: assignment of read-only location ‘*(ccs + 1u)’
ccs= csc; // Good
csc[1]='n'; // Good
csc= ccs; // Bad - error: assignment of read-only variable ‘csc’
char const **ccss= &ccs; // Good
char const **ccss1= &csc; // Bad - warning: initialization from incompatible pointer type
char * const *cscs= &csc; // Good
char * const *cscs1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc= &pca1; // Good
char ** const cssc1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc2= &csc; // Bad - warning: initialization discards ‘const’
// qualifier from pointer target type
*ccss[1]= 'x'; // Bad - error: assignment of read-only location ‘**(ccss + 8u)’
*ccss= ccs; // Good
*ccss= csc; // Good
ccss= ccss1; // Good
ccss= cscs; // Bad - warning: assignment from incompatible pointer type
*cscs[1]= 'y'; // Good
*cscs= ccs; // Bad - error: assignment of read-only location ‘*cscs’
*cscs= csc; // Bad - error: assignment of read-only location ‘*cscs’
cscs= cscs1; // Good
cscs= cssc; // Good
*cssc[1]= 'z'; // Good
*cssc= ccs; // Bad - warning: assignment discards ‘const’
// qualifier from pointer target type
*cssc= csc; // Good
*cssc= pca2; // Good
cssc= ccss; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cscs; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cssc1; // Bad - error: assignment of read-only variable ‘cssc’
}
Sintassi:
datatype *const var;
char *const
rientra in questo caso.
/*program to illustrate the behaviour of constant pointer */
#include<stdio.h>
int main(){
int a=10;
int *const ptr=&a;
*ptr=100;/* we can change the value of object but we cannot point it to another variable.suppose another variable int b=20; and ptr=&b; gives you error*/
printf("%d",*ptr);
return 0;
}
Sintassi:
const datatype *var
o datatype const *var
const char*
rientra in questo caso.
/* program to illustrate the behavior of pointer to a constant*/
#include<stdio.h>
int main(){
int a=10,b=20;
int const *ptr=&a;
printf("%d\n",*ptr);
/* *ptr=100 is not possible i.e we cannot change the value of the object pointed by the pointer*/
ptr=&b;
printf("%d",*ptr);
/*we can point it to another object*/
return 0;
}
char * const e const char *?
const char * p;
// il valore non può essere modificato
char * const p;
// l'indirizzo non può essere modificato
const char * const p;
// entrambi non possono essere modificati.
Il const
modificatore viene applicato al termine immediatamente alla sua sinistra. L'unica eccezione a ciò è quando non c'è nulla alla sua sinistra, quindi si applica a ciò che è immediatamente alla sua destra.
Questi sono tutti modi equivalenti di dire "puntatore costante a una costante char
":
const char * const
const char const *
char const * const
char const const *
Due regole
If const is between char and *, it will affect the left one.
If const is not between char and *, it will affect the nearest one.
per esempio
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
Vorrei sottolineare che l'utilizzo int const *
(o const int *
) non riguarda un puntatore che punta a una const int
variabile, ma che questa variabile è const
per questo puntatore specifico.
Per esempio:
int var = 10;
int const * _p = &var;
Il codice sopra si compila perfettamente bene. _p
punta a una const
variabile, sebbene var
non sia costante.
Ricordo dal libro ceco su C: leggi la dichiarazione che inizi con la variabile e vai a sinistra. Così per
char * const a;
puoi leggere come: " a
è una variabile di tipo puntatore costante a char
",
char const * a;
puoi leggere come: " a
è un puntatore a variabile costante di tipo char. Spero che questo ti aiuti.
Bonus:
const char * const a;
Leggerai come a
è puntatore costante alla variabile costante di tipo char.