C ++

Cara menggunakan Penunjuk C ++

Cara menggunakan Penunjuk C ++
Ingatan komputer adalah rangkaian sel yang panjang. Ukuran setiap sel dipanggil byte. Byte adalah ruang yang dihuni oleh watak Inggeris abjad. Objek dalam erti kata biasa adalah sekumpulan bait berturut-turut dalam ingatan. Setiap sel mempunyai alamat, yang merupakan bilangan bulat, biasanya ditulis dalam bentuk heksadesimal. Terdapat tiga cara untuk mengakses objek dalam ingatan. Objek boleh diakses menggunakan apa yang dikenali sebagai penunjuk. Ia dapat diakses menggunakan apa yang dikenali sebagai rujukan. Ia masih boleh diakses menggunakan pengecam. Fokus artikel ini adalah pada penggunaan petunjuk dan rujukan. Dalam C ++, terdapat objek runcing dan objek penunjuk. Objek runcing mempunyai objek yang menarik. Objek penunjuk mempunyai alamat ke objek runcing.

Anda perlu mempunyai pengetahuan asas dalam C ++, termasuk pengecam, fungsi, dan susunannya; untuk memahami artikel ini.

Objek penunjuk dan objek runcing, masing-masing mempunyai pengecamnya.

Alamat Pengendali, &

Ini adalah pengendali yang tidak berubah. Apabila diikuti oleh pengecam, ia mengembalikan alamat objek pengecam. Pertimbangkan pernyataan berikut:

int ptdInt;

Berikut adalah kod, ungkapan berikut, akan mengembalikan alamat yang dikenal pasti oleh ptdInt:

& ptdInt

Anda tidak perlu mengetahui alamat (nombor) yang tepat seperti yang anda kodkan.

Pengendali Tidak Langsung, *

Ini adalah pengendali yang tidak berubah dalam konteks petunjuk. Ia biasanya ditaip di hadapan pengecam. Jika digunakan dalam deklarasi pengenal, maka pengecam adalah objek penunjuk yang hanya menyimpan alamat objek runcing. Sekiranya digunakan di hadapan pengenal objek penunjuk, untuk mengembalikan sesuatu, maka barang yang dikembalikan adalah nilai objek runcing.

Membuat Penunjuk

Lihat segmen kod berikut:

apungan ptdFloat;
terapung * ptrFloat;
ptrFoat = &ptdFloat;

Segmen bermula dengan pengisytiharan objek runcing, ptdFloat. ptdFloat adalah pengecam, yang hanya mengenal pasti objek apungan. Objek sebenar (nilai) mungkin diberikan kepadanya, tetapi dalam kes ini, tidak ada yang diberikan kepadanya. Selanjutnya di segmen, terdapat pernyataan objek penunjuk. Pengendali tidak langsung di hadapan pengecam ini bermaksud ia harus memegang alamat objek runcing. Jenis objek, terapung di awal pernyataan, bermaksud objek runcing adalah pelampung. Objek penunjuk selalu sama dengan objek runcing. ptrFoat adalah pengecam, yang hanya mengenal pasti objek penunjuk.

Dalam pernyataan terakhir kod, alamat objek runcing ditugaskan ke objek penunjuk. Perhatikan penggunaan alamat-operator, &.

Pernyataan terakhir (baris) di atas menunjukkan, bahawa setelah menyatakan objek penunjuk tanpa inisialisasi, anda tidak memerlukan operator tidak langsung, ketika anda harus menginisialisasi. Sebenarnya, adalah kesalahan sintaks untuk menggunakan pengendali tidak langsung pada baris ketiga (terakhir).

Objek penunjuk dapat dinyatakan dan diinisialisasi oleh objek runcing dalam satu pernyataan, seperti berikut:

apungan ptdFloat;
terapung * ptrFoat = &ptdFloat;

Baris pertama segmen kod sebelumnya dan yang sama, adalah sama. Baris kedua dan ketiga dari segmen kod sebelumnya telah digabungkan menjadi satu penyataan di sini.

Perhatikan dalam kod di atas bahawa ketika menyatakan dan menginisialisasi objek penunjuk, pengendali tidak langsung harus digunakan. Walau bagaimanapun, ia tidak digunakan jika inisialisasi dilakukan selepas itu. Objek penunjuk diinisialisasi dengan alamat objek runcing.

Dalam segmen kod berikut, pengendali tidak langsung digunakan untuk mengembalikan kandungan objek runcing.

int ptdInt = 5;
int * ptrInt = &ptdInt;
cout << *ptrInt << '\n';

Keluarannya adalah 5.

Dalam pernyataan terakhir di sini, pengendali tidak langsung telah digunakan untuk mengembalikan nilai yang ditunjukkan, oleh pengenal penunjuk. Jadi, apabila digunakan dalam deklarasi, pengenal untuk pengendali tidak langsung akan memegang alamat objek runcing. Apabila digunakan dalam ungkapan kembali, dalam kombinasi dengan pengenal penunjuk, pengendali tidak langsung mengembalikan nilai objek runcing.

Memperuntukkan Sifar kepada Penunjuk

Objek penunjuk harus selalu mempunyai jenis objek runcing. Semasa menyatakan objek penunjuk, jenis data objek runcing harus digunakan. Walau bagaimanapun, nilai sifar perpuluhan dapat diberikan kepada penunjuk seperti pada segmen kod berikut:

int ptdInt = 5;
int * ptrInt;
ptrInt = 0;
atau di segmen,
int ptdInt = 5;
int * ptrInt = 0;

Dalam kedua-dua kes, penunjuk (pengecam) disebut penunjuk nol; maksudnya, ia menunjuk ke mana-mana. Artinya, ia tidak mempunyai alamat objek runcing. Di sini, 0 adalah sifar perpuluhan dan bukan sifar heksadesimal. Sifar heksadesimal akan menunjukkan alamat pertama memori komputer.

Jangan cuba mendapatkan nilai yang ditunjukkan oleh penunjuk nol. Sekiranya anda mencubanya, program mungkin menyusun, tetapi mungkin tidak dapat dilaksanakan.

Nama Array sebagai Penunjuk Tetap

Pertimbangkan susunan berikut:

int arr [] = 000, 100, 200, 300, 400;

Nama array, arr sebenarnya adalah pengecam yang mempunyai alamat elemen pertama array. Ungkapan berikut mengembalikan nilai pertama dalam tatasusunan:

* arr

Dengan array, operator kenaikan, ++ berkelakuan berbeza. Daripada menambah 1, ia menggantikan alamat penunjuk, dengan alamat elemen seterusnya dalam tatasusunan. Walau bagaimanapun, nama array adalah penunjuk tetap; bermaksud kandungannya (alamat) tidak boleh diubah atau ditingkatkan. Jadi, untuk kenaikan, alamat permulaan array harus diberikan kepada penunjuk tidak tetap seperti berikut:

int * ptr = arr;

Sekarang, ptr dapat ditingkatkan untuk menunjuk ke elemen array yang seterusnya. ptr telah dinyatakan di sini sebagai objek penunjuk. Tanpa * di sini, ia tidak akan menjadi petunjuk; ia akan menjadi pengecam untuk menyimpan objek int dan tidak menyimpan alamat memori.

Segmen kod berikut akhirnya menunjukkan elemen keempat:

++ptr;
++ptr;
++ptr;

Kod berikut menghasilkan nilai keempat array:

int arr [] = 000, 100, 200, 300, 400;
int * ptr = arr;
++ptr;
++ptr;
++ptr;
cout << *ptr << '\n';

Keluarannya ialah 300.

Nama Fungsi sebagai Pengecam

Nama fungsi adalah pengenal fungsi. Pertimbangkan definisi fungsi berikut:

int fn ()

cout << "seen" << '\n';
pulangan 4;

fn adalah pengecam fungsi. Ekspresi,

& fn

mengembalikan alamat fungsi dalam memori. fn seperti objek runcing. Deklarasi berikut menyatakan penunjuk ke fungsi:

int (* func) ();

Pengecam untuk objek runcing dan pengecam untuk objek penunjuk berbeza. func adalah penunjuk fungsi. fn adalah pengecam fungsi. Oleh itu, fungsi boleh dibuat untuk menunjukkan kepada fn seperti berikut:

func = &fn;

Nilai (isi) func adalah alamat fn. Kedua-dua pengenal tersebut dapat dihubungkan dengan pernyataan inisialisasi seperti berikut:

int (* func) () = &fn;

Perhatikan perbezaan dan persamaan dalam menangani pointer fungsi dan skalar pointer. func adalah penunjuk fungsi; ia adalah objek runcing; ia dinyatakan berbeza dari penunjuk skalar.

Fungsi boleh dipanggil dengan,

fn ()
atau
func ()

Ia tidak boleh dipanggil dengan * func ().

Apabila fungsi mempunyai parameter, tanda kurung kedua mempunyai jenis parameter dan tidak perlu mempunyai pengenal untuk parameter. Program berikut menggambarkan ini:

#sertakan
menggunakan ruang nama std;
float fn (float fl, int dalam)

pulangan fl;

int utama ()

apungan (* func) (apungan, int) = &fn;
float val = func (2.5, 6);
cout << val << '\n';
pulangan 0;

Keluarannya adalah 2.5.

Rujukan C ++

Merujuk dalam C ++ hanyalah cara untuk menghasilkan sinonim (nama lain) untuk pengecam. Ia menggunakan & operator, tetapi tidak dengan cara yang sama seperti & digunakan untuk petunjuk. Pertimbangkan segmen kod berikut:

int myInt = 8;
int & yourInt = myInt;
cout << myInt << '\n';
cout << yourInt << '\n';

Keluarannya adalah:

8
8

Pernyataan pertama memulakan pengecam, myInt; i.e. myInt dinyatakan dan dibuat untuk menahan nilai, 8. Pernyataan kedua menjadikan pengecam baru, yourInt sinonim dengan myInt. Untuk mencapai ini, & operator diletakkan di antara jenis data dan pengenal baru dalam deklarasi. Pernyataan cout menunjukkan bahawa kedua-dua pengecam itu adalah sinonim. Untuk mengembalikan nilai dalam kes ini, anda tidak perlu mendahului dengan * . Hanya gunakan pengecam.

myInt dan yourInt di sini, bukan dua objek yang berbeza. Mereka adalah dua pengecam yang berbeza yang merujuk (mengenal pasti) lokasi yang sama dalam memori yang mempunyai nilai, 8. Sekiranya nilai myInt diubah, maka nilaiInInt anda juga akan berubah secara automatik. Sekiranya nilaiInInt anda diubah, nilai myInt juga akan berubah secara automatik.

Rujukan adalah jenis yang sama.

Rujukan kepada Fungsi

Sama seperti anda boleh merujuk pada skalar, anda juga dapat merujuk pada fungsi. Walau bagaimanapun, pengekodan rujukan ke fungsi berbeza dari pengekodan rujukan ke skalar. Program berikut menggambarkan ini:

#sertakan
menggunakan ruang nama std;
float fn (float fl, int dalam)

pulangan fl;

int utama ()

float (& func) (float, int) = fn;
float val = func (2.5, 6);
cout << val << '\n';
pulangan 0;

Keluarannya adalah 2.5.

Perhatikan pernyataan pertama dalam fungsi utama, yang menjadikan func sebagai sinonim dari fn. Kedua-duanya merujuk fungsi yang sama. Perhatikan penggunaan tunggal dan kedudukan &. Jadi & adakah pengendali rujukan di sini dan bukan alamat-pengendali. Untuk memanggil fungsi, hanya gunakan salah satu nama.

Pengecam rujukan tidak sama dengan pengecam penunjuk.

Fungsi mengembalikan Penunjuk

Dalam program berikut, fungsi mengembalikan penunjuk, yang merupakan alamat objek runcing:

#sertakan
menggunakan ruang nama std;
float * fn (float fl, int in)

terapung * fll = &fl;
kembali fll;

int utama ()

apungan * val = fn (2.5, 6);
cout << *val << '\n';
pulangan 0;

Keluarannya adalah 2.5

Pernyataan pertama dalam fungsi, fn () ada hanya untuk membuat objek penunjuk. Perhatikan penggunaan tunggal dan kedudukan * dalam tandatangan fungsi. Perhatikan juga bagaimana penunjuk (alamat), diterima dalam fungsi utama () oleh objek penunjuk yang lain.

Fungsi mengembalikan Rujukan

Dalam program berikut, fungsi mengembalikan rujukan:

#sertakan
menggunakan ruang nama std;
float & fn (float fl, int dalam)

terapung & frr = fl;
balik frr;

int utama ()

apungan & val = fn (2.5, 6);
cout << val << '\n';
pulangan 0;

Keluarannya adalah 2.5.

Pernyataan pertama dalam fungsi, fn () ada hanya untuk membuat rujukan. Perhatikan penggunaan tunggal dan kedudukan & dalam tandatangan fungsi. Perhatikan juga bagaimana rujukan, diterima dalam fungsi utama () oleh rujukan lain.

Menghantar Penunjuk ke Fungsi

Dalam program berikut, penunjuk, yang sebenarnya adalah alamat objek terapung, dikirim sebagai argumen ke fungsi:

#sertakan
menggunakan ruang nama std;
float fn (float * fl, int in)

pulangan * fl;

int utama ()

apungan v = 2.5;
apungan val = fn (& v, 6);
cout << val << '\n';
pulangan 0;

Keluarannya adalah 2.5

Perhatikan penggunaan dan kedudukan * untuk parameter float dalam tandatangan fungsi. Sebaik sahaja penilaian fungsi fn () dimulakan, pernyataan berikut dibuat:

terapung * fl = & v;

Kedua-dua fl dan & v menunjuk ke objek runcing yang sama yang memegang 2.5. * fl pada penyata pengembalian bukan deklarasi; maksudnya, nilai objek runcing yang ditunjukkan oleh objek penunjuk.

Menyampaikan Rujukan untuk Fungsi

Dalam program berikut, rujukan dikirim sebagai argumen untuk fungsi:

#sertakan
menggunakan ruang nama std;
float fn (float & fl, int in)

pulangan fl;

int utama ()

apungan v = 2.5;
apungan val = fn (v, 6);
cout << val << '\n';
pulangan 0;

Keluarannya adalah 2.5

Perhatikan penggunaan dan kedudukan & untuk parameter apungan dalam tandatangan fungsi. Sebaik sahaja penilaian fungsi fn () dimulakan, pernyataan berikut dibuat:

terapung & fl = v;

Menyerahkan Array ke Fungsi

Program berikut menunjukkan cara meneruskan array ke fungsi:

#sertakan
menggunakan ruang nama std;
int fn (int arra [])

kembali arra [2];

int utama ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
cout << val << '\n';
pulangan 0;

Keluarannya adalah 200.

Dalam program ini, susunan yang dilalui. Perhatikan bahawa parameter tandatangan fungsi mempunyai deklarasi array kosong. Argumen dalam panggilan fungsi hanyalah nama array yang dibuat.

Bolehkah Fungsi C ++ mengembalikan Array?

Fungsi dalam C ++ dapat mengembalikan nilai array, tetapi tidak dapat mengembalikan array. Penyusunan program berikut menghasilkan mesej ralat:

#sertakan
menggunakan ruang nama std;
int fn (int arra [])

balik arra;

int utama ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
pulangan 0;

Penunjuk Penunjuk

Penunjuk boleh menunjuk ke penunjuk yang lain. Maksudnya, objek penunjuk boleh mempunyai alamat objek penunjuk yang lain. Mereka semua mesti mempunyai jenis yang sama. Segmen kod berikut menggambarkan ini:

int ptdInt = 5;
int * ptrInt = &ptdInt;
int ** ptrptrInt = &ptrInt;
cout << **ptrptrInt << '\n';

Keluarannya adalah 5.

Dalam pengisytiharan pointer-to-pointer, double * digunakan. Untuk mengembalikan nilai objek runcing terakhir, double * masih digunakan.

Array Penunjuk

Program berikut menunjukkan cara membuat kod array penunjuk:

#sertakan
menggunakan ruang nama std;
int utama ()

int num0 = 000, num1 = 100, num2 = 200, num3 = 300, num4 = 400;
int * no0 = & num0, * no1 = & num1, * no2 = & num2, * no3 = & num3, * no4 =&num4;
int * arr [] = no0, no1, no2, no3, no4;
cout << *arr[4] << '\n';
pulangan 0;

Keluarannya adalah:

400

Perhatikan penggunaan dan kedudukan * dalam deklarasi array. Perhatikan penggunaan * ketika mengembalikan nilai dalam array. Dengan titik penunjuk, dua * terlibat. Dalam kes array penunjuk, satu * telah dijaga, kerana pengenal array adalah penunjuk.

Susunan Rentetan Panjang Berubah

String literal adalah pemalar yang mengembalikan penunjuk. Susunan rentetan panjang berubah-ubah adalah susunan penunjuk. Setiap nilai dalam array adalah penunjuk. Penunjuk adalah alamat ke lokasi memori dan mempunyai ukuran yang sama. Rentetan dengan panjang yang berbeza terdapat di tempat lain dalam ingatan, bukan dalam larik. Program berikut menggambarkan penggunaan:

#sertakan
menggunakan ruang nama std;
int utama ()

const char * arr [] = "wanita", "budak lelaki", "gadis", "dewasa";
cout << arr[2] << '\n';
pulangan 0;

Keluarannya adalah "gadis".

Pengisytiharan larik dimulakan dengan kata terpelihara, "const" untuk pemalar; diikuti dengan "char" untuk watak, kemudian tanda bintang, * untuk menunjukkan bahawa setiap elemen adalah penunjuk. Untuk mengembalikan rentetan dari array, * tidak digunakan, kerana sifat penunjuk setiap rentetan tersirat. Sekiranya * digunakan, maka elemen rentetan pertama akan dikembalikan.

Pointer ke Fungsi mengembalikan Pointer

Program berikut menggambarkan bagaimana penunjuk ke fungsi mengembalikan penunjuk dikodkan:

#sertakan
menggunakan ruang nama std;
int * fn ()

int num = 4;
int * inter = #
pulangan antara;

int utama ()

int * (* func) () = &fn;
int val = * func ();
cout << val << '\n';
pulangan 0;

Keluarannya adalah 4.

Deklarasi pointer ke fungsi mengembalikan pointer adalah serupa dengan deklarasi pointer ke fungsi biasa tetapi didahului dengan tanda bintang. Pernyataan pertama dalam fungsi utama () menggambarkan ini. Untuk memanggil fungsi menggunakan penunjuk, mendahului dengan *.

Kesimpulannya

Untuk membuat penunjuk ke skalar, lakukan sesuatu seperti,

apungan menunjuk;
terapung * penunjuk = &pointed;

* mempunyai dua makna: dalam deklarasi, ia menunjukkan penunjuk; untuk mengembalikan sesuatu, itu adalah untuk nilai objek runcing.

Nama larik adalah penunjuk berterusan ke elemen pertama bagi larik.

Untuk membuat penunjuk ke fungsi, anda boleh melakukannya,

int (* func) () = &fn;

di mana fn () adalah fungsi yang ditentukan di tempat lain dan func adalah penunjuk.

& mempunyai dua makna: dalam deklarasi, ia menunjukkan rujukan (sinonim) ke objek yang sama dengan pengecam lain; semasa mengembalikan sesuatu, itu bermaksud alamat-of.

Untuk membuat rujukan ke fungsi, anda boleh melakukannya,

float (& refFunc) (float, int) = fn;

di mana fn () adalah fungsi yang ditentukan di tempat lain dan refFunc adalah rujukan.

Apabila fungsi mengembalikan penunjuk, nilai yang dikembalikan harus diterima oleh penunjuk. Apabila fungsi mengembalikan rujukan, nilai yang dikembalikan harus diterima oleh rujukan.

Ketika meneruskan pointer ke fungsi, parameternya adalah deklarasi, sedangkan argumen adalah alamat objek runcing. Ketika meneruskan rujukan ke fungsi, parameternya adalah deklarasi, sedangkan argumennya adalah rujukan.

Semasa meneruskan array ke fungsi, parameternya adalah deklarasi sementara argumen adalah nama array tanpa []. Fungsi C ++ tidak mengembalikan array.

Penunjuk ke penunjuk memerlukan dua * daripada satu, jika sesuai.

Chrys

Cara menangkap dan streaming sesi permainan anda di Linux
Pada masa lalu, bermain permainan hanya dianggap sebagai hobi, tetapi seiring dengan berjalannya waktu, industri permainan menyaksikan pertumbuhan yan...
Permainan Terbaik untuk Dimainkan dengan Penjejakan Tangan
Oculus Quest baru-baru ini memperkenalkan idea hebat penjejakan tangan tanpa pengawal. Dengan jumlah permainan dan aktiviti yang semakin meningkat yan...
Cara Menunjukkan Overlay OSD dalam Aplikasi dan Permainan Linux Skrin Penuh
Bermain permainan skrin penuh atau menggunakan aplikasi dalam mod skrin penuh bebas gangguan dapat memisahkan anda dari maklumat sistem yang relevan y...