const char * ve char const * - aynı mı?


81

Benim anlayışıma göre, constdeğiştiriciler sağdan sola okunmalıdır. Bundan anlıyorum:

const char*

char öğeleri değiştirilemeyen bir göstericidir, ancak işaretçinin kendisi yapabilir ve

char const*

mutablekarakterlere sabit bir göstericidir .

Ancak aşağıdaki kod için aşağıdaki hataları alıyorum:

const char* x = new char[20];
x = new char[30];   //this works, as expected
x[0] = 'a';         //gives an error as expected

char const* y = new char[20];
y = new char[20];   //this works, although the pointer should be const (right?)
y[0] = 'a';         //this doesn't although I expect it to work

Peki ... hangisi o? Anladığım veya derleyicim (VS 2005) yanlış mı?


35
Şüpheye düştüğünüzde daima Spiral Kuralı kullanın .
Alok

"... char öğeleri değiştirilebilir, ancak işaretçinin kendisi yapabilir ve ..." - bence bu "can" lardan biri için "yapamam" demek istedin, ama nasıl olduğunu bilmiyorum
Kafanız

1
Bu web sitesini deneyin: www.cdecl.org
yasouser

Derleyici asla yanılmaz;)
monolith

Yanıtlar:


129

Aslında standarda göre constelemanı doğrudan solunda değiştirir . Kullanımı constilanı başında sadece uygun bir zihinsel kısa yoldur. Dolayısıyla aşağıdaki iki ifade eşdeğerdir:

char const * pointerToConstantContent1;
const char * pointerToConstantContent2;

İşaretçinin kendisinin değiştirilmediğinden emin constolmak için yıldız işaretinden sonra yerleştirilmelidir:

char * const constantPointerToMutableContent;

Hem işaretçiyi hem de işaret ettiği içeriği korumak için iki sabit kullanın.

char const * const constantPointerToConstantContent;

Ben şahsen kabul ettik hep ben işaretçi ben sabit tutmak isteyen parçası olsa bile ben tutarlılığı korumak şekilde değiştirmek için değil niyetinde bölümünü sonra const koyarak.


23
'uygun steno', daha kısa olmayan ve normal kurallara uymayan bir şeyin ilginç bir tanımlamasıdır.
beetstra

Standart hangi siparişi kullandığınızı gerçekten umursamıyor. Bölüm 7.1.6 sadece her iki yeri de gösterir ve sadece bir yerde kullanılmasını söyler.
edA-qa mort-ora-y

1
@beetstra Katılıyorum. Biraz daha net olması için bunu "uygun zihinsel kısayol" olarak değiştirdim.
Greyson

31

İşe yarıyor çünkü ikisi de aynı. Bu konuda kafan karışabilir

const char*  // both are same
char const*

ve

char* const  // unmutable pointer to "char"

ve

const char* const  // unmutable pointer to "const char"

[Bunu hatırlamak için, işte basit bir kural, "*" önce tüm LHS'yi etkiler ]


Tamam, şimdi anladım. Çok teşekkürler.
Luchian Grigore

1
unmutable pointer to char*.Bu işaret eden unmutable işaretçisi chardeğil char *.
Alok

25

Çünkü kural şudur:

KURAL: constSolda hiçbir şey olmadığı sürece sola bağlanır, sonra sağa bağlanır :)

bu nedenle, bunlara şu şekilde bakın:

(const --->> char)*
(char <<--- const)*

ikisi de aynı! oh ve --->>ve <<---operatörler DEĞİLDİR, sadece göstermek constiçin bağlamalar.


2
evet, doğru operatördür -->>ve yalnızca değerler üzerinde çalışır. Deneyin int i = 8; std::cout << (i -->> 1) << std::endl;:)
Alexander Malakhov

11

( 2 basit değişken başlatma sorusundan )

Aşağıdakilerle ilgili gerçekten iyi bir kural const:

Sağdan Sola Bildirimleri Okuyun.

(bkz. Vandevoorde / Josutiss "C ++ Şablonları: Tam Kılavuz")

Örneğin:

int const x; // x is a constant int
const int x; // x is an int which is const

// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p;        // p is a reference to const-int
int * const * p;     // p is a pointer to const-pointer to int.

Bu genel kurala uyduğumdan beri, bu tür beyanları bir daha asla yanlış yorumlamadım.

(: sisab retcarahc-rep a no ton, sisab nekot-rep a no tfel-ot-thgir naem I hguohT: tidE


+1 Bu harika, teşekkürler! Yıllardır bu tür şeylerin etrafından dolaşmaya çalışıyorum const char* constve senin sayende şimdi anlıyorum.
OMGtechy

5

Ben her zaman şu şekilde yorumlamaya çalışıyorum:

char *p

     |_____ start from the asterisk. The above declaration is read as: "content of `p` is a `char`".

char * const p

     |_____ again start from the asterisk. "content of constant (since we have the `const` 
            modifier in the front) `p` is a `char`".

char const *p

           |_____ again start from the asterisk. "content of `p` is a constant `char`".

Umarım yardımcı olur!


0

Her iki durumda da sabit bir karaktere işaret ediyorsunuz.

const char * x  //(1) a variable pointer to a constant char
char const * x  //(2) a variable pointer to a constant char
char * const x  //(3) a constant pointer to a variable char
char const * const x //(4) a constant pointer to a constant char
char const * const * x //(5) a variable pointer to a constant pointer to a constant char
char const * const * const x //(6) can you guess this one?

Varsayılan olarak, consthemen solda olan şey için geçerlidir, ancak (1) 'de olduğu gibi, önünde hiçbir şey yoksa hemen sağında olana da uygulanabilir.


Sonuncusu: Bir sabit değişken gösterici, sabit bir işaretçiye, sabit bir karaktere.
Secko

"Sabit değişken işaretçi" ile "sabit işaretçi" yi kastediyorsanız, onu çivilediniz kardeşim!
Lino Mediavilla

(5) 'te bu, sabit bir karaktere sabit bir göstericinin değişken göstericisidir, çünkü "x" tanımlayıcısından önce son yıldız işaretinin sağında "const" yoktur. Fakat sabit bir işaretçi haline gelen (6) 'da geri kalanı aynı kaldı.
Lino Mediavilla
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.