Pointer konstan ke pointer ke pointer ...

Pendahuluan


Baru-baru ini mereka mendekati saya dengan pertanyaan, "apa itu dan bagaimana menggunakannya?", Menampilkan kode berikut:

extern "C" { void byteMaskDowngrade(byte***const byteMask, const byte *const *const && source) { // - . } //  . } 

Kolega ini adalah kolega kerja saya, dan kami tidak segera memahami apa arti parameter dalam deklarasi fungsi (bagi mereka yang tertarik di mana pengumuman seperti itu mungkin diperlukan: dalam kriptografi).

Dan untuk mengantisipasi kemungkinan masalah dari rekan kerja di bengkel, saya memutuskan untuk membuat artikel ini, meletakkannya sebagai lembar contekan, yaitu jawaban untuk dua pertanyaan:

  1. Bagaimana cara menulis iklan semacam itu di sini?
  2. Dan bagaimana cara membacanya dengan benar?

"*"


Kasus dengan satu tanda bintang adalah yang paling umum, namun, kesalahpahaman juga mungkin terjadi di sini:

  • Bagaimana cara:

    • Jadi:

       const byte p; 
    • Atau lebih:

       byte const p; 

  • Atau dalam hal entri '*':

    • Jadi:

       byte *const p; 
    • Atau lebih:

       const byte *p; 

Sebenarnya, dari sudut pandang kompiler, kehadiran tanda bintang dan posisinya dalam ekspresi menimbulkan pertanyaan tepi karena makna akhir dari entri akan berbeda. Kehadiran const specifier dalam kasus di atas tidak membuat perbedaan ketika mempertimbangkan posisinya relatif terhadap tipe data, namun, situasinya berubah secara dramatis ketika pointer muncul: satu, dua, tiga ... yah, Anda mengerti:

 void p() { //   . byte * a = new byte{1}; a++; // . a[0]++; // . //    . const byte * b = new byte{1}; b++; // . //b[0]++; // . //    . byte *const c = new byte{1}; //c++; // . c[0]++; // . //     . const byte *const d = new byte{1}; //d++; // . //d[0]++; // . } 

Semua ini terlihat lebih menarik ketika pointer kedua muncul (di sini aturan membaca yang efisien untuk penulisan sudah mulai dilacak):

 void pp() { //     . byte ** a = new byte * { new byte{1} }; a++; // . a[0]++; // . a[0][0]++; // . //      . const byte ** b = new const byte * { new byte{1}}; b++; // . b[0]++; // . //b[0][0]++; // . //      . byte *const * c = new byte * { new byte{1}}; c++; // . //c[0]++; // . c[0][0]++; // . //      . byte * *const d = new byte * { new byte{1}}; //d++; // . d[0]++; // . d[0][0]++; // . //       . const byte *const * e = new const byte *const { new byte{1}}; e++; // . //e[0]++; // . //e[0][0]++; // . //       . const byte * *const f = new const byte * { new byte{1}}; //f++; // . f[0]++; // . //f[0][0]++; // . //       . byte *const *const g = new byte *const { new byte{1}}; //g++; // . //g[0]++; // . g[0][0]++; // . //        . const byte *const *const h = new const byte *const { new byte{1}}; //h++; // . //h[0]++; // . //h[0][0]++; // . } 

Seperti yang Anda lihat, pointer ganda dapat direpresentasikan dalam sebanyak 8 cara berbeda, masing-masing mendefinisikan cara khusus menggunakan data target.

Aturan untuk membaca ungkapan tersebut adalah sebagai berikut:

  • cari tanda '=' pada ekspresi dan baca ekspresi dari kanan ke kiri;
  • lewati nama variabel;
  • pertemuan selanjutnya baik '*', yang berarti pointer reguler, atau '* const' - pointer konstan;
  • dengan demikian kita membaca sampai tipe data (byte) ditemukan;
  • dan kata terakhir di sebelah kiri tipe data dapat berupa const, yang keberadaannya berarti bahwa keseluruhan konstruksi ini mengacu pada data yang tidak dapat diubah; jika const tidak, maka itu mungkin.

Bentuk menulis dan membaca ini membuatnya mudah dibaca dan dimengerti bahkan ungkapan yang paling canggih sekalipun)

Berikut ini contoh kumpulan ekspresi lengkap dengan triple pointer:

"Sial"


 void ppp() { //       . byte *** a = new byte * * { new byte * {new byte{1}} }; a++; // . a[0]++; // . a[0][0]++; // . a[0][0][0]++; // . //        . const byte *** b = new const byte * * { new const byte * {new byte{1}} }; b++; // . b[0]++; // . b[0][0]++; // . //b[0][0][0]++; // . //        . byte*const * * c = new byte *const * { new byte *const {new byte{1}} }; c++; // . c[0]++; // . //c[0][0]++; // . c[0][0][0]++; // . //        . byte * *const * d = new byte * *const { new byte * {new byte{1}} }; d++; // . //d[0]++; // . d[0][0]++; // . d[0][0][0]++; // . //        . byte *** const e = new byte * * { new byte * {new byte{1}} }; //e++; // . e[0]++; // . e[0][0]++; // . e[0][0][0]++; // . //         . const byte *const * * f = new const byte *const * { new const byte *const {new byte{1}} }; f++; // . f[0]++; // . //f[0][0]++; // . //f[0][0][0]++; // . //         . const byte * *const * g = new const byte * *const{ new const byte * {new byte{1}} }; g++; // . //g[0]++; // . g[0][0]++; // . //g[0][0][0]++; // . //         . const byte * * *const h = new const byte * *{ new const byte * {new byte{1}}}; //h++; // . h[0]++; // . h[0][0]++; // . //h[0][0][0]++; // . //         . byte *const * *const i = new byte *const * { new byte *const {new byte{1}}}; //i++; // . i[0]++; // . //i[0][0]++; // . i[0][0][0]++; // . //         . byte * *const *const j = new byte * *const { new byte * {new byte{1}}}; //j++; // . //j[0]++; // . j[0][0]++; // . j[0][0][0]++; // . //         . byte *const *const * k = new byte *const *const {new byte *const{new byte{1}}}; k++; // . //k[0]++; // . //k[0][0]++; // . k[0][0][0]++; // . //           const //           . const byte *const *const *const m = new const byte *const *const {new const byte *const {new byte{1}}}; //m++; // . //m[0]++; // . //m[0][0]++; // . //m[0][0][0]++; // . } 

Source: https://habr.com/ru/post/id468605/


All Articles