Jaka jest różnica pomiędzy:
char * const
i
const char *
Jaka jest różnica pomiędzy:
char * const
i
const char *
Odpowiedzi:
Różnica polega na tym, że const char *
jest wskaźnikiem do const char
, podczas gdy char * const
jest stałym wskaźnikiem do char
.
Po pierwsze, wskazanej wartości nie można zmienić, ale wskaźnik może być. Po drugie, wskazywana wartość może ulec zmianie, ale wskaźnik nie może (podobnie jak odwołanie).
Istnieje również
const char * const
który jest stałym wskaźnikiem do stałego char (więc nic o tym nie można zmienić).
Uwaga:
Następujące dwie formy są równoważne:
const char *
i
char const *
Dokładny powód tego jest opisany w standardzie C ++, ale ważne jest, aby pamiętać i unikać zamieszania. Znam kilka standardów kodowania, które wolą:
char const
nad
const char
(ze wskaźnikiem lub bez), aby położenie const
elementu było takie samo jak ze wskaźnikiem const
.
const int *foo,*bar;
że zarówno zadeklarować foo
i bar
być int const *
, lecz int const *foo, *bar
by oświadczyć foo
się int const *
i bar
być int *
. Myślę, typedef int * intptr; const intptr foo,bar;
że zadeklarowałbym obie zmienne int * const
; Nie znam żadnego sposobu użycia deklaracji połączonej do utworzenia dwóch zmiennych tego typu bez typedef.
I believe const int *foo,*bar; would declare both foo and bar to be int const *
: Tak. but int const *foo, *bar would declare foo to be a int const * and bar to be int *
: Nie! Byłoby dokładnie tak samo jak w poprzednim przypadku. (Zobacz ideone.com/RsaB7n, gdzie pojawia się ten sam błąd zarówno dla Foo, jak i dla paska). I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const
: Tak. I don't know any way to use a combined declaration to create two variables of that type without a typedef
Cóż, int *const foo, *const bar;
. Składnia deklaratora C ...
int const *foo, *volatile bar
zrobił bar
? Zrób to jednocześnie const
i volatile
? Czyste rozdzielenie Tęsknię Pascala nazw zadeklarowane-zmiennych i ich rodzaje (wskaźnik do tablicy wskaźników do liczb całkowitych będzie var foo: ^Array[3..4] of ^Integer
.;. `To byłoby trochę śmieszne zagnieżdżonych w nawiasach, co w C, myślę
int const *foo, *volatile bar
” część typu to int const
(zatrzymuje się przed *
), a deklaratory to *foo
(wyrażenie *foo
będzie oznaczać an int const
) i *volatile bar
; czytanie od prawej do lewej (dobra zasada dla kwalifikatorów cv ), foo
jest wskaźnikiem do const int i bar
jest zmiennym wskaźnikiem do const int (sam wskaźnik jest zmienny, wskazany int jest [dostępny jako] const).
[3..4]
składni, więc weźmy tablicę 10 elementów) int *(*foo)[10];
. Odzwierciedla swoje (przyszłe) użycie jako wyrażenia: *(*foo)[i]
(z i
liczbą całkowitą w zakresie [0, 10)
tj. [0, 9]
) Najpierw wyrejestruje się, foo
aby dostać się do tablicy, a następnie uzyska dostęp do elementu z indeksem i
(ponieważ postfiks []
wiąże się mocniej niż przedrostek *
), a następnie wyrejestrowuje ten element, w końcu dając int
(patrz ideone.com/jgjIjR ). Ale typedef
to ułatwia (patrz ideone.com/O3wb7d ).
Aby uniknąć zamieszania, zawsze dołączaj kwalifikator 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
nie odnosi się do typu: (const int *const)
. Na lepsze lub gorsze (gorsze, jeśli mnie pytasz) kwalifikator const, zarówno w C, jak i C ++, ma być postfix: cf const funkcja składowa void foo(int a) const;
. Możliwość zadeklarowania const int
jest wyjątkiem, a nie regułą.
const
zawsze modyfikuje rzecz, która jest przed nią (po lewej stronie), Z WYJĄTKIEM, gdy jest to pierwsza rzecz w deklaracji typu, gdzie modyfikuje rzecz, która pojawia się po niej (po prawej stronie).
Te dwa są takie same:
int const *i1;
const int *i2;
definiują wskaźniki do const int
. Możesz zmienić miejsce i1
i i2
punkty, ale nie możesz zmienić wartości, na którą wskazują.
To:
int *const i3 = (int*) 0x12345678;
definiuje const
wskaźnik do liczby całkowitej i inicjuje go, aby wskazywał na miejsce w pamięci 12345678. Możesz zmienić int
wartość pod adresem 12345678, ale nie możesz zmienić adresu, który i3
wskazuje.
const * char
jest nieprawidłowym kodem C i nie ma znaczenia. Być może chciałeś zapytać o różnicę między const char *
a a char const *
, a może różnicę między const char *
a a char * const
?
const char*
jest wskaźnikiem do stałego znaku
char* const
jest stałym wskaźnikiem do znaku
const char* const
jest stałym wskaźnikiem do stałego znaku
Ogólna zasada: przeczytaj definicję od prawej do lewej!
const int *foo;
Oznacza „ foo
wskazuje ( *
) na coś int
, czego nie można zmienić ( const
)”.
Dla programisty oznacza to: „Nie zmienię wartości tego, co foo
wskazuje”.
*foo = 123;
lub foo[0] = 123;
byłby nieprawidłowy.foo = &bar;
jest dozwolone.int *const foo;
Oznacza „ foo
nie można zmienić ( const
) i wskazuje ( *
) na int
”.
Dla programisty oznacza to „Nie zmienię adresu pamięci, który foo
dotyczy”.
*foo = 123;
lub foo[0] = 123;
jest dozwolone.foo = &bar;
byłby nieważny.const int *const foo;
Oznacza „ foo
nie można zmienić ( const
) i wskazuje ( *
) na„ int
nie można zmienić ( const
) ”.
Dla programisty oznacza to: „Nie zmienię wartości tego, na co foo
wskazuje, ani nie zmienię adresu, który foo
odnosi się do”.
*foo = 123;
lub foo[0] = 123;
byłby nieprawidłowy.foo = &bar;
byłby nieważny.const char * x Tutaj X jest zasadniczo wskaźnikiem znaku, który wskazuje na stałą wartość
char * const x odnosi się do wskaźnika znaku, który jest stały, ale położenie, które wskazuje, można zmienić.
const char * const x jest kombinacją 1 i 2, co oznacza, że jest stałym wskaźnikiem znaku, który wskazuje na stałą wartość.
const * char x spowoduje błąd kompilatora. nie można tego zadeklarować.
char const * x jest równy pkt 1.
ogólna zasada jest taka, że jeśli const ma nazwę var, wówczas wskaźnik będzie stały, ale położenie wskazujące można zmienić , w przeciwnym razie wskaźnik będzie wskazywał stałe położenie, a wskaźnik może wskazywać inne położenie, ale zawartości wskazanego położenia nie można zmienić .
Wiele odpowiedzi zawiera konkretne techniki, kciuki itp., Aby zrozumieć ten konkretny przypadek deklaracji zmiennej. Ale istnieje ogólna technika rozumienia każdej deklaracji:
Reguła zgodna z ruchem wskazówek zegara / spiralna
ZA)
const char *a;
Zgodnie z regułą a
zgodną z ruchem wskazówek zegara / spirala jest stały wskaźnik do znaku. Co oznacza, że znak jest stały, ale wskaźnik może się zmienić. tzn. a = "other string";
jest w porządku, ale a[2] = 'c';
się nie skompiluje
B)
char * const a;
Zgodnie z regułą a
jest stałym wskaźnikiem do znaku. tzn. możesz zrobić, a[2] = 'c';
ale nie możesza = "other string";
Zakładam, że masz na myśli const char * i char * const.
Pierwszy, const char *, jest wskaźnikiem do stałego znaku. Sam wskaźnik jest zmienny.
Drugi char * const jest stałym wskaźnikiem do znaku. Wskaźnik nie może się zmienić, znak, na który wskazuje, może.
A potem jest const char * const, w którym wskaźnik i znak nie mogą się zmienić.
Oto szczegółowe wyjaśnienie dotyczące kodu
/*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’
}
Składnia:
datatype *const var;
char *const
wchodzi w zakres tej sprawy.
/*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;
}
Składnia:
const datatype *var
lub datatype const *var
const char*
wchodzi w zakres tej sprawy.
/* 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 i const char *?
const char * p;
// wartości nie można zmienić
char * const p;
// adresu nie można zmienić
const char * const p;
// oba nie mogą zostać zmienione.
const
Modyfikator stosuje się określenie natychmiast po jego lewej stronie. Jedynym wyjątkiem jest sytuacja, gdy nie ma nic po jego lewej stronie, to dotyczy to tego, co znajduje się bezpośrednio po jego prawej stronie.
Są to wszystkie równoważne sposoby powiedzenia „stały wskaźnik do stałej char
”:
const char * const
const char const *
char const * const
char const const *
Dwie zasady
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.
na przykład
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
Chciałbym zaznaczyć, że użycie int const *
(lub const int *
) nie polega na wskaźniku wskazującym na const int
zmienną, ale że ta zmienna jest const
przeznaczona dla tego konkretnego wskaźnika.
Na przykład:
int var = 10;
int const * _p = &var;
Powyższy kod kompiluje się doskonale. _p
wskazuje na const
zmienną, chociaż var
sama nie jest stała.
Pamiętam z czeskiej książki o C: przeczytaj deklarację, że zaczynasz od zmiennej i idziesz w lewo. Więc dla
char * const a;
możesz odczytać jako: „ a
zmienna typu stałego wskaźnika do char
”,
char const * a;
możesz przeczytać jako: " a
jest wskaźnikiem do stałej zmiennej typu char. Mam nadzieję, że to pomoże.
Premia:
const char * const a;
Będziesz czytał tak jak a
stały wskaźnik do stałej zmiennej typu char.