Const int *, const int * const və int const * arasında fərq nədir?

Mən həmişə const int* , const int * constint const * dan düzgün istifadə etmək üçün necə korlanmışdım. Nə və edə bilməyəcəyini müəyyən edən bir sıra qaydalar varmı?

Mən etmək lazımdır ki, hər şeyi bilmək istəyirəm və bütün bunlar tapşırıqlara, funksiyaların ötürülməsinə və s.

1043
17 июля '09 в 16:28 2009-07-17 16:28 ultraman iyul ayının 17-də saat 16: 09-da başlayır
@ 14 cavab

Geri oxuyun ( saat yönlü / spiral qayda olaraq idarə olunur):

  • int* - int üçün göstərici
  • int const * - const int üçün göstərici
  • int * const - const göstəricisi int
  • int const * const - const int üçün const göstəricisi

İndi ilk const tipi hər iki tərəfdə belə ola bilər:

  • const int * == int const *
  • const int * const == int const * const

Çıldırmaq istəyirsinizsə, bunları edə bilərsiniz:

  • int ** - int ** üçün pointer göstəricisi
  • int ** const - int göstəricisi üçün göstərici const
  • int * const * - göstəricisi int üçün intransit
  • int const ** - const int üçün göstərici göstəricisi
  • int * const * const - pointer const'ını int anlayışına keçir
  • ...

Və const dəyərini dəqiq şəkildə anladığımıza əmin olmaq üçün

 const int* foo; int *const bar; //note, you actually need to set the pointer //here because you can't change it later ;) 

foo , sabit bir tamsayıya dəyişən göstəricidir. Bu, göstərdiyiniz şeyi dəyişməyə imkan verir, ancaq göstərdiyiniz dəyəri deyil. Bu, ən çox C-stil stringsində görünür, burada bir const char göstəricisiniz var. Göstərdiyiniz xəttini dəyişə bilərsiniz, lakin bu xətlərin məzmununu dəyişə bilməzsiniz. Bu simli proqramın məlumat seqmentində olduğunda vacibdir və dəyişilməməlidir.

bar dəyişdirilə bilən bir dəyəri sabit və ya sabit göstəricidir. Bu əlavə sintaksis şəkərsiz bir keçid kimi. Buna görə, bir qayda olaraq, NULL göstəricilərə ehtiyacınız yoxdursa T* const göstəricisini istifadə edəcəyi bir link istifadə edəcəksiniz.

1811
17 июля '09 в 16:29 2009-07-17 16:29 Cavab Matt Price tərəfindən 17 iyul 17: 09-da verilir. 2009-07-17 16:29

Saat yönlü / spiral qayda haqqında bilməyənlər üçün: dəyişən adı ilə başlayın, növbəti istiqamətə (bu halda geri hərəkət et) saat istiqamətində hərəkət edin və ya . Sözün sonuna qədər təkrarlayın.

Demo versiyası:

2019

248
10 июля '15 в 5:15 2015-07-10 05:15 Cavab Şijing Lv 10 iyul 15:15 -da verilir. 2015-07-10 05:15

Buradakı hər şeyi söylədiyini düşünürəm, amma əlavə etmək istəyirəm ki, typedef çəkinin! Bu, yalnız bir mətn əvəz deyil.

Məsələn:

 typedef char *ASTRING; const ASTRING astring; 

astring növü char * const deyil, const char * . Bu, həmişə tipin hüququ ilə bağlı const və başlamamamın səbəblərindən biridir.

126
17 июля '09 в 16:39 2009-07-17 16:39 cavab Kaz Dragon tərəfindən iyulun 17-də '09 'da 16:39' da verilmişdir 2009-07-17 16:39

Çoxları kimi, hər kəs qeyd etdi:

const X* p , X* const pconst X* const p arasında fərq nədir?

Sağdan sola işarə bəyannamələrini oxumalısınız.

  • const X* p "const" olan "p nöqtələrinə" aiddir: X obyekti p ilə dəyişdirilə bilməz.

  • X* const p "p, sabit deyil olan X-yə konst bir göstəricidir" deməkdir: göstərici p dəyişə bilməz, ancaq obyektin X-dən p-ə dəyişə bilərsiniz.

  • const X* const p "p, const olan const X üçün göstəricidir" deməkdir: siz göstərici p özünüzü dəyişdirə bilməzsiniz və obyekti X-dən p-ə dəyişə bilməzsiniz.

45
17 июля '09 в 16:36 2009-07-17 16:36 Cavab luke tərəfindən iyul ayının 17-də saat 16: 36-da verilmişdir 2009-07-17 16:36
  • Daimi link:

    Sabit olan bir dəyişənə istinad (burada, int). Bağlantılar əsl dəyərdən daha kiçik ölçülüdür, lakin bir yan təsiri var və bunun səbəbi faktiki dəyişən bir alias kimi göründüyünə görə dəyişən bir keçid olaraq keçid veririk. Biz yanlışlıqla əsas dəyişənimizi təxəllüyə çıxışı ilə tam şəkildə dəyişə bilərik, buna görə də biz bu yan təsirin qarşısını almaq üçün qalıcı hesab edirik.

     int var0 = 0; const int  = var0; ptr1 = 8; // Error var0 = 6; // OK 
  • Sabit göstəricilər

    Sabit göstərici bir dəyişənə işarə etdikdə, hər hansı bir dəyişənə işarə edə bilməz.

     int var1 = 1; int var2 = 0; int *const ptr2 =  ptr2 =  // Error 
  • Sabit göstərici

    Bir göstəricinin göstərdiyi dəyişənin dəyərini dəyişdirə bilməyəcəyi bir göstərici sabit olaraq göstərici olaraq bilinir.

     int const * ptr3 =  *ptr3 = 4; // Error 
  • Daimi göstərici sabitdir

    Sabit bir sabit pointer, hansı ünvana dəydiyini dəyişdirə bilməyəcək bir göstəricidir və bu ünvanı saxlanılan dəyəri dəyişdirə bilməz.

     int var3 = 0; int var4 = 0; const int * const ptr4 =  *ptr4 = 1; // Error ptr4 =  // Error 
40
17 мая '14 в 23:21 2014-05-17 23:21 Cavab Behrooz Tabesh tərəfindən verilir 17 May '14, 23:21 2014-05-17 23:21

Bu sual, mənim sualımda qeyd etdiyimi yerinə yetirmək istədiyimi dəqiq bir tip identifikatorundan sonra daimi olaraq göstərir? p>

Qısacası, bir qaydanı xatırlamanın ən asan yoludur ki, "const" onunla əlaqəli olduğunu izah edir. Buna görə sizin sualınızdakı "int const *" int intensivdir və "int * const" göstərici sabit olduğunu bildirir.

Kimsə bunu ön plana çıxarmağa qərar verərsə (məsələn, "const int *"), bu halda xüsusi bir istisna olaraq, o, bundan sonra obyektə tətbiq olunur.

Bir çox insanlar bu xüsusi istisnadan istifadə etmək istəyirlər, çünki onlar daha yaxşı görünürlər. Mən istəmirəm, çünki bir istisna və beləliklə şeyi qarışdırır.

16
17 июля '09 в 16:52 2009-07-17 16:52 cavab TED 17 iyul '09 'da 16:52' da verilmişdir 2009-07-17 16:52

Ümumi qayda, const sözü dərhal öncə nə üçün tətbiq olunur. Istisna ilk const .

  • const int* int const*"int sabitinə göstərici" deməkdir.
  • const int* const int const* const ilə uyğun gəlir və "int sabit sabit pointer" deməkdir.

Düzenle: Dos və Yapılandırmalar üçün, bu cavab kifayət deyilsə, istədiyinizi aydınlaşdırmaq olarmı?

14
17 июля '09 в 16:30 2009-07-17 16:30 Cavab AProgrammer tərəfindən iyulun 17-də saat 16.30-da verilir. 2009-07-17 16:30

Sadə istifadə 'const

Sadə istifadə adlandırılmış bir sabit elan edir. Bunu etmək üçün dəyişən bir sanki sabit olaraq bəyan edin, ancaq onu qarşısında əlavə edin. Dərhal konstruktorda başlamalısınız, çünki, əlbəttə ki, bu dəyəri dəyişə biləcəyi dəyəri daha sonra təyin edə bilməzsiniz. Məsələn,

 const int Constant1=96; 

96 dəyəri ilə "Constant1" adlandırıla bilməyən bir tamsaylı sabitlik yaradır.

Belə sabitlər proqramda istifadə olunan parametrlər üçün faydalıdır, lakin proqram tərtib olunduqdan sonra dəyişdirilməsinə ehtiyac yoxdur. Programmers üçün "preprocessor" #define komanda üzərində üstünlük təşkil edir, çünki kompilyatorun özü tərəfindən başa düşülür və istifadə olunur, sadəcə əsas kompilyatora çatmadan əvvəl proqramın mətni ilə əvəzlənmir, ona görə də səhv mesajlar çox faydalıdır.

Bu da göstəricilərlə işləyir, ancaq bir göstəricinin və ya işarə etdiyinin sabit olduğunu yoxsa hər ikisini də müəyyənləşdirdiyinə əmin olun. Məsələn,

 const int * Constant2 

Constant2 sabit tamsayıya dəyişən bir göstəricidir və bəyan edir

 int const * Constant2 

- Alternativ sintaksis, eynidır

 int * const Constant3 

Constant3 dəyişən tamsayıya davamlı bir göstərici olduğunu bildirir

 int const * const Constant4 

constant4 sabit bir tamsayı üçün sabit bir göstəricidir. Əsasən, "const" dərhal solda olanları ifadə edir (heç bir şey olmadığı hallarda, bu vəziyyətdə bu, dərhal sağ olan hər şeyə aiddir).

ref: http://duramecho.com/ComputerInformation/WhyHowCppConst.html

12
17 июля '09 в 16:31 2009-07-17 16:31 cavab 17 iyul 17: 09-da ufukgun verilir. 2009-07-17 16:31

Bu kitabla C ++ Guru Scott Meyers ilə tanış olana qədər mənimlə eyni şübhə oldunuz. Bu kitabın üçüncü bəndinə baxın ki, o, const istifadə barədə ətraflı danışır.

Yalnız bu ipucuya əməl edin.

  • Sözü const solunda göstərilirsə, bu da sabit olaraq göstərilir.
  • Sözü const ulduzun sağında göstərilirsə, göstərici özü sabitdir.
  • Hər iki tərəfdə const görünürsə, ikisi də qalıcıdır.
7
21 марта '15 в 16:56 2015-03-21 16:56 Cavab 21 mart, '15 'də saat 16:56' da veriləcək

C ++ 'da, const düzgünlüyünü əhatə edən bir çox digər incə nöqtələr var. Buradakı sual yalnız C haqqında olduğunu düşünürəm, amma C ++ etiketi olduğundan bəzi nümunələr verəcəyəm:

  • TYPE const > kimi strings kimi, və ya bir obyektin dəyişdirilməsinə və ya nüsxəsini maneə törətmək kimi tez-tez böyük arqumentlər keçir. Məsələn:

    TYPE TYPE::operator=(const TYPE { ... return *this; }

    Lakin TYPE const heç bir mənada deyil, çünki əlaqələr həmişə const.

  • Sınıfı const olaraq dəyişdirməyən sinif metodlarını hər zaman göstərməlisiniz, əks halda siz üsulu TYPE const > dan çağırırsınız. Məsələn:

    bool TYPE::operator==(const TYPE const { ... }

  • Hər iki qaynaq dəyəri və metodu konst olduğunda ümumi vəziyyətlər mövcuddur. Məsələn:

    const TYPE TYPE::operator+(const TYPE const { ... }

    Əslində, const üsulları qeyri-const üçün istinad kimi daxili sinif məlumatlarını geri verməməlidir.

  • Nəticədə, const yükünü istifadə edərək, hem const hem de qeyri-sabit bir metod yaratmaq üçün çox vaxt lazımdır. Məsələn, T const operator[] (unsigned i) const; , ehtimal ki, qeyri-sabit versiyaya da ehtiyacınız olacaq:

    inline T operator[] (unsigned i) { return const_cast<char static_cast<const TYPE ); }

Məsələn, C-də const funksiyaları yoxdur, üzv olmayan funksiyalar C ++-da const ola bilməz, const üsulları yan təsirləri ola bilər və kompilyator funksiya çağırışlarının təkrarlanmasından yayınmaq üçün const funksiyalarından istifadə edə bilməz. Əslində, hətta sadə istinad int const > onunla əlaqəli dəyərin başqa yerdə dəyişəcəyini göstərə bilər.

5
13 сент. Sep 13-də Jeff Burdges tərəfindən verilmiş cavab 2011-09-13 13:50 '11 'da 13:50' də 2011-09-13 13:50

C və C ++ bəyannamələrinin sintaksisi uğursuz bir sınaq, orijinal dizaynerlər kimi dəfələrlə təsvir edilmişdir.

Bunun əvəzinə, növü "pointer to Type " Type ; Ona Ptr_ :

 template< class Type > using Ptr_ = Type*; 

İndi Ptr_<char> üçün göstəricidir.

Ptr_<const char> bir const char üçün göstəricidir.

const Ptr_<const char> , const Ptr_<const char> const göstəricisidir.

Orada

2019

Cavab Cheers və b. 06 янв. - Alf Jan 06 2016-01-06 03:12 '16 'da 3:12' də 2016-01-06 03:12 'də

Sadə, lakin çətin. const hər hansı bir məlumat növünə ( int , char , float , və s.) Dəyişdirə bilərik.

Aşağıdakı nümunələri baxın.


const int *p ==> *p yalnız oxunur [ p bir sabit tamsayı üçün bir göstəricidir]

int const *p ==> *p yalnız oxunur [ p bir sabit tamsayı üçün göstəricidir]


int *p const ==> Yanlış bildiriş. Derleyici bir sözdizimi hatası üretir.

int *const p ==> p yalnız oxunur [ p tamsayı üçün sabit göstəricidir]. p göstəricisi burada oxunduğu üçün bəyannamə və tərif eyni yerdə olmalıdır.


const int *p const ==> Yanlış bildiriş. Derleyici bir sözdizimi hatası üretir.

const int const *p ==> *p yalnız oxunur

const int *const p1 ==> *pp yalnız oxunur [ p sabit bir tamsayı üçün sabit göstəricidir]. p göstəricisi burada oxunduğu üçün bəyannamə və tərif eyni yerdə olmalıdır.


int const *p const ==> Yanlış bildiriş. Derleyici bir sözdizimi hatası üretir.

int const int *p ==> Yanlış bildiriş. Derleyici bir sözdizimi hatası üretir.

int const const *p ==> *p yalnız oxumaq və int const *p bərabərdir

int const *const p ==> *pp yalnız oxunur [ p bir sabit tamsayı üçün sabit göstəricidir]. p göstəricisi burada oxunduğu üçün bəyannamə və tərif eyni yerdə olmalıdır.

5
04 янв. Abhijit Sahu tərəfindən verilmiş cavab Jan 04 2015-01-04 16:10 '15 at 16:10 2015-01-04 16:10

Hər iki tərəfdə int bir sabit int sabit bir göstərici edəcək .

 const int *ptr=> 

və ya

 int const *ptr=> 

'*' əmrindən sonra const bir int üçün sabit bir göstərici göstərəcəkdir.

 int *const ptr=> 

Bu vəziyyətdə onlar daimi bir tamsayıdır , lakin onların heç biri daimi göstəricidir.

  const int *ptr1= *ptr2=> 

Bu halda, hər şey sabit bir tamsayıdır və ptr2 daimi tamsayı üçün sabit bir göstəricidir . Amma ptr1 daimi göstərici deyil.

 int const *ptr1= *const ptr2=> 
2
23 сент. Cavab 23 avqustda Hunter tərəfindən verilmişdir 2018-09-23 11:44 '18 saat 11:44 'də 2018-09-23 11:44' də

Bu əsasən ikinci xəttə aiddir: ən yaxşı təcrübələr, tapşırıqlar, funksiyaların parametrləri və s.

Ümumi təcrübə. const olan bütün const etməyə çalışın. Yoxsa bunu fərqli bir şəkildə etmək üçün bütün const başlamalı və proqramın fəaliyyət göstərməsi üçün lazım olan minimum const tamamilə aradan const . Bu, const-düzgünlüyünə nail olmaqda böyük kömək olacaq və insanların dəyişdirməməli olan şeyləri təyin etməyə çalışdıqları zaman incə səhvlərin tətbiq olunmamasına kömək edəcəkdir.

Const_cast <> vəba kimi çəkinin. Bunun üçün bir və ya iki hüquqi istifadə var, lakin onlar çox az və bir-birindən uzaqdır. const obyektini dəyişdirməyə const , ilk const elan edəni tapmaq və problemin baş verməsi barədə fikir birliyinə çatmaq üçün bu məsələni onlarla müzakirə etmək daha yaxşı olacaq.

Bu, çox rahatlıqla təyinatlara gətirib çıxarır. Əgər const deyilsə, yalnız bir şey təyin edə bilərsiniz. Əgər sabit bir şey təyin etmək istəyirsinizsə, yuxarıda baxın. Bəyannamələrdə int const *foo;int * const bar; Fərqli şeylər const - burada digər cavablar bu problemi çox yaxşı əks etdirir, ona daxil olmayacağam.

İşlev parametrləri:

Qiymətə görə gedin: məsələn. void func(int param) sizə, hər halda, zəng saytında. Funksiyanın void func(int const param) funksiyanı void func(int const param) kimi istifadə etmək üçün variantları var, lakin bu, zəng zamanı funksiyanı köçürən hər hansı köçürülmüş dəyər dəyişdirilə bilmədikdə, yalnız funksiyanın özündə deyil, zəng edənə təsir etməyəcəkdir.

Referansa keçid: məsələn. void func(int > İndi vacibdir. func param dəyişdirilməsinə icazə verildiyi və hər hansı bir saytın nəticələri ilə nəticələnə biləcəyi açıqlandı. void func(int const > etmək üçün bəyannamənin dəyişdirilməsi void func(int const > müqaviləni dəyişir və funksiyanın artıq param dəyişə bilməyəcəyini təmin edir, yəni qəbul edilən şey geri qaytarılır. Başqalarının qeyd etdiyinə görə, bu dəyişiklik etmək istəmədiyiniz böyük bir obyektin ucuzca ötürülməsi üçün çox faydalıdır. Sertifikatın ötürülməsi böyük bir obyektin dəyəri ilə keçməsindən çox ucuzdur.

Göstərici atlayın: məsələn. void func(int *param)void func(int const *param) Bu ikisi, onların istinad nümunələri ilə kifayət qədər sinonimlidir, şərtlə ki, çağırılan funksiya artıq başqa bir müqavilə zəmanəti nullptr almaq heç vaxt.

Bu mövzuda fikir. Bu vəziyyətdə düzgünlüyün sübutu qətiyyətlə çətin, səhv etmək üçün çox asandır. Beləliklə, şans almaq və həmişə nullptr üçün göstərici parametrlərini nullptr . Acı və əzabdan qurtulacaqsınız və uzun müddətdə səhvləri tapa bilərsiniz. Çekin qiymətinə gəlincə, bu ucuzdur və kompilyatora yerləşdirilən statik analiz onu idarə edə biləcəyi hallarda, optimallaşdırıcı hər halda onu silməyəcəkdir. GCC üçün MSVC və ya WOPR (məncə düşünürəm) üçün vaxt kodu kodunu yaratmaq və onu bütöv bir proqram şəklində əldə edəcəksiniz, yəni mənbə kodu modulu sərhədindən keçən funksiyaları çağırmaqda belə.

Günün sonunda yuxarıda göstərilənlərin hamısı göstəricilərə istinadlar hər zaman üstünlük verdiyi zaman çox etibarlı bir vəziyyət təşkil edir. Onlar bütün yerlərdə daha təhlükəsizdirlər.

1
15 марта '18 в 10:59 2018-03-15 10:59 cavab 15 mart '18 'də saat 10:59' də veriləcək. 2018-03-15 10:59

tags digər suallar və ya bir sual