C ++

Penukaran Piawai C ++

Penukaran Piawai C ++
Terdapat dua jenis entiti dalam C ++, jenis asas dan jenis sebatian. Jenis asas adalah jenis skalar. Jenis kompaun adalah jenis entiti selebihnya. Penukaran boleh berlaku dari satu jenis entiti ke jenis lain yang sesuai. Pertimbangkan program berikut:

#sertakan
#sertakan
menggunakan ruang nama std;
int utama ()

int rt1 = sqrt (5);
int rt2 = sqrt (8);
cout<pulangan 0;

Keluarannya adalah 2, 2, bermaksud bahawa program ini telah mengembalikan punca kuasa dua 5 sebagai 2 dan punca kuasa dua 8 juga sebagai 2. Jadi, dua penyataan pertama di utama () fungsi telah meletakkan jawapan bagi punca kuasa dua 5 dan punca kuasa dua 8. Artikel ini tidak membincangkan lantai atau siling di C++. Sebaliknya, artikel ini membincangkan penukaran satu jenis C ++ ke jenis C ++ lain yang sesuai; menunjukkan penghampiran nilai yang dibuat, kehilangan ketepatan, atau kekangan yang ditambahkan atau dikeluarkan. Pengetahuan asas mengenai C ++ adalah prasyarat untuk memahami artikel ini.

Kandungan Artikel

  • Penukaran Integral
  • Penukaran Titik Terapung
  • Penukaran Terapung-Integral
  • Kedudukan Penukaran Integer
  • Promosi Integral
  • Penukaran Aritmetik Biasa
  • Promosi Titik Terapung
  • Penukaran Penunjuk
  • Fungsi untuk Penukaran Penunjuk
  • Penukaran Boolean
  • Lvalue, prvalue, dan xvalue
  • Nilai X
  • Penukaran Lvalue-to-rvalue
  • Penukaran Array-to-Pointer
  • Penukaran Fungsi-ke-Penunjuk
  • Penukaran Pemanfaatan Sementara
  • Penukaran Kelayakan
  • Kesimpulannya

Penukaran Integral

Penukaran integral adalah penukaran integer. Bilangan bulat yang tidak ditandatangani termasuk "char yang tidak ditandatangani," "int yang tidak ditandatangani," "int yang tidak ditandatangani," "int yang tidak ditandatangani," dan "int panjang yang tidak ditandatangani."Bilangan bulat yang ditandatangani termasuk" tanda arang "," int pendek, "" int, "" int panjang, "dan" panjang panjang int."Setiap jenis int harus disimpan dalam bait sebanyak pendahulunya. Untuk kebanyakan sistem, satu jenis entiti boleh ditukar menjadi jenis yang sesuai tanpa masalah. Masalahnya berlaku ketika menukar dari jenis julat yang lebih besar ke jenis julat yang lebih kecil, atau ketika menukar nombor bertanda ke nombor yang tidak ditandatangani yang sesuai.

Setiap penyusun mempunyai nilai maksimum yang dapat diambil untuk int pendek. Sekiranya nombor yang lebih tinggi daripada maksimum, yang dimaksudkan untuk int, ditetapkan ke int pendek, penyusun akan mengikuti beberapa algoritma dan mengembalikan nombor dalam julat int pendek. Sekiranya pengaturcara bernasib baik, penyusun akan memberi amaran tentang masalah penggunaan penukaran yang tidak sesuai. Penjelasan yang sama berlaku untuk penukaran jenis int lain.

Pengguna harus melihat dokumentasi penyusun untuk menentukan nilai had bagi setiap jenis entiti.

Sekiranya nombor int pendek ditandatangani negatif akan ditukar menjadi nombor int pendek tidak bertanda tangan, penyusun akan mengikuti beberapa algoritma dan mengembalikan nombor positif dalam julat int pendek yang tidak ditandatangani. Penukaran seperti ini harus dielakkan. Penjelasan yang sama berlaku untuk penukaran jenis int lain.

Sebilangan nombor bulat, kecuali 0, boleh ditukar menjadi Boolean true. 0 ditukar menjadi Boolean false. Kod berikut menggambarkan ini:

int a = -27647;
apungan b = 2.5;
int c = 0;
bool a1 = a;
bool b1 = b;
bool c1 = c;
cout<cout<cout<Keluarannya adalah:

1 untuk benar
1 untuk benar
0 untuk palsu

Penukaran Titik Terapung

Jenis titik terapung termasuk "pelampung", "dua kali lipat" dan "ganda panjang."Jenis titik terapung tidak dikelompokkan menjadi ditandatangani dan tidak ditandatangani, seperti bilangan bulat. Setiap jenis boleh mempunyai nombor yang ditandatangani atau tidak ditandatangani. Jenis titik apungan harus mempunyai ketepatan sekurang-kurangnya sama dengan pendahulunya. Artinya, "double double" harus mempunyai ketepatan yang sama atau lebih besar untuk "double," dan "double" harus mempunyai ketepatan yang sama atau lebih besar untuk "mengambang."

Ingat bahawa julat jenis titik terapung tidak berterusan; sebaliknya, ia dalam beberapa langkah. Semakin besar ketepatan jenisnya, semakin kecil langkahnya, dan semakin besar bilangan bait untuk menyimpan nombor tersebut. Oleh itu, apabila nombor titik terapung ditukar dari jenis ketepatan yang lebih rendah ke jenis ketepatan yang lebih tinggi, pengaturcara mesti menerima peningkatan ketepatan yang salah dan kemungkinan peningkatan jumlah bait untuk penyimpanan nombor. Apabila nombor terapung ditukar dari jenis ketepatan yang lebih tinggi ke jenis ketepatan yang lebih rendah, pengaturcara mesti menerima kerugian ketepatan. Sekiranya bilangan bait untuk penyimpanan nombor mesti dikurangkan, maka penyusun akan mengikuti beberapa algoritma dan mengembalikan nombor sebagai pengganti (yang mungkin bukan yang dikehendaki oleh pengaturcara). Juga, ingatlah masalah di luar jangkauan.

Penukaran Terapung-Integral

Nombor terapung ditukar menjadi bilangan bulat dengan memotong bahagian pecahan. Kod berikut menggambarkan ini:

apungan f = 56.953;
int i = f;
cout<Keluarannya adalah 56. Julat untuk pelampung dan bilangan bulat mesti serasi.

Apabila bilangan bulat diubah menjadi pelampung, nilai yang ditampilkan sebagai apungan adalah sama seperti yang diketik sebagai bilangan bulat. Walau bagaimanapun, setara apungan mungkin bernilai tepat atau mempunyai sedikit perbezaan pecahan yang tidak ditunjukkan. Sebab perbezaan pecahan adalah bahawa nombor titik terapung ditunjukkan dalam komputer dalam langkah pecahan kecil, dan mewakili bilangan bulat dengan tepat adalah kebetulan. Jadi, walaupun bilangan bulat yang ditampilkan sebagai pelampung sama seperti yang ditaip, paparannya mungkin merupakan penghampiran dari apa yang disimpan.

Kedudukan Penukaran Integer

Segala jenis bilangan bulat mempunyai peringkat yang telah diberikan kepadanya. Peringkat ini membantu dalam penukaran. Kedudukannya relatif; peringkat tidak berada pada tahap tetap. Kecuali char dan char yang ditandatangani, tidak ada dua bilangan bulat yang ditandatangani memiliki peringkat yang sama (dengan anggapan char ditandatangani). Jenis bilangan bulat yang tidak ditandatangani mempunyai kedudukan yang sama dengan jenis bilangan bulat yang sesuai. Kedudukannya adalah seperti berikut:

  • Dengan andaian bahawa char ditandatangani, maka char dan ditandatangani char mempunyai pangkat yang sama.
  • Peringkat jenis bilangan bulat yang ditandatangani lebih besar daripada kedudukan jenis bilangan bulat yang ditandatangani dengan bilangan bait penyimpanan yang lebih kecil. Jadi, pangkat int panjang ditandatangani lebih besar daripada pangkat int panjang ditandatangani, yang lebih besar daripada pangkat int panjang ditandatangani, lebih besar daripada pangkat int panjang ditandatangani, yang lebih besar daripada pangkat char ditandatangani.
  • Pangkat bagi setiap jenis bilangan bulat yang tidak ditandatangani sama dengan peringkat bagi jenis bilangan bulat yang ditandatangani.
  • Peringkat char yang tidak ditandatangani sama dengan kedudukan char yang ditandatangani.
  • bool mempunyai pangkat paling rendah; pangkatnya kurang daripada yang ditandatangani.
  • char16_t mempunyai pangkat yang sama dengan int pendek. char32_t mempunyai pangkat yang sama dengan int. Untuk penyusun g ++, wchar_t mempunyai kedudukan yang sama dengan int.

Promosi Integral

Promosi Integral adalah Promosi Integer. Tidak ada sebab mengapa bilangan bulat byte lebih sedikit tidak dapat diwakili oleh bilangan bulat byte yang lebih besar. Promosi Integer berkaitan dengan semua perkara berikut:

  • Int pendek ditandatangani (dua bait) boleh ditukar menjadi int bertanda (empat bait). Int pendek yang tidak ditandatangani (dua bait) boleh ditukar menjadi int yang tidak ditandatangani (empat bait). Catatan: menukar int pendek untuk int panjang atau int panjang panjang menyebabkan pembaziran penyimpanan (lokasi objek) bait dan pembaziran memori. Bool, char16_t, char32_t, dan wchar_t dikecualikan dari promosi ini (dengan penyusun g ++, char32_t dan wchar_t mempunyai bilangan bait yang sama).
  • Dengan penyusun g ++, jenis char16_t dapat ditukar menjadi jenis int yang ditandatangani atau jenis int yang tidak ditandatangani; jenis char32_t boleh ditukar menjadi jenis int yang ditandatangani atau jenis int yang tidak ditandatangani; dan jenis wchar_t boleh ditukar menjadi jenis int yang ditandatangani atau tidak ditandatangani.
  • Jenis bool boleh ditukar menjadi jenis int. Dalam kes ini, benar menjadi 1 (empat bait) dan salah menjadi 0 (empat bait). Int mungkin ditandatangani atau ditandatangani.
  • Promosi integer juga ada untuk jenis penghitungan yang tidak tersekat - lihat kemudian.

Penukaran Aritmetik Biasa

Pertimbangkan kod berikut:

apungan f = 2.5;
int i = f;
cout<Kod menyusun tanpa menunjukkan amaran atau kesalahan, memberikan output dari 2, yang mungkin tidak seperti yang diharapkan. = adalah pengendali binari kerana memerlukan operan kiri dan kanan. Pertimbangkan kod berikut:

int i1 = 7;
int i2 = 2;
float flt = i1 / i2;
cout<Keluarannya adalah 3, tetapi ini salah; sepatutnya 3.5. Pengendali bahagian, /, juga merupakan pengendali binari.

C ++ mempunyai penukaran aritmetik biasa yang mesti diketahui oleh pengaturcara untuk mengelakkan kesilapan dalam pengekodan. Penukaran aritmetik biasa pada pengendali binari adalah seperti berikut:

  • Sekiranya salah satu operan adalah jenis "double long," maka operan akan ditukar menjadi double double.
  • Jika tidak, jika salah satu operan berganda, yang lain akan ditukar menjadi dua kali ganda.
  • Jika tidak, jika salah satu operan terapung, yang lain akan ditukar menjadi apungan. Dalam kod di atas, hasil i1 / i2 secara rasmi 2; sebab itulah flt adalah 2. Hasil perduaan, /, diterapkan sebagai operan yang tepat kepada pengendali binari, =. Jadi, nilai akhir 2 adalah float (bukan int).

LAIN, PROMOSI INTEGER AKAN MENGAMBIL TEMPAT SEBAGAI BERIKUT:

  • Sekiranya kedua-dua operan mempunyai jenis yang sama, maka penukaran tidak berlaku lagi.
  • Jika tidak, jika kedua-dua operan ditandai jenis integer atau kedua-duanya adalah jenis integer yang tidak ditandatangani, maka operan jenis dengan peringkat bilangan bulat yang lebih rendah akan ditukar kepada jenis operan dengan pangkat yang lebih tinggi.
  • Jika tidak, jika satu operan ditandatangani dan yang lain tidak ditandatangani, dan jika jenis operan yang tidak ditandatangani lebih besar daripada atau sama dengan peringkat jenis operan yang ditandatangani, dan jika nilai operan yang ditandatangani lebih besar daripada atau sama dengan sifar, maka operan yang ditandatangani akan ditukarkan kepada jenis operan yang tidak ditandatangani (dengan jarak pertimbangan). Sekiranya operan yang ditandatangani adalah negatif, maka penyusun akan mengikuti algoritma dan mengembalikan nombor yang mungkin tidak dapat diterima oleh pengaturcara.
  • Jika tidak, jika satu operan adalah jenis bilangan bulat yang ditandatangani dan yang lain adalah jenis bilangan bulat yang tidak ditandatangani, dan jika semua nilai yang mungkin dari jenis operan dengan jenis bilangan bulat yang tidak ditandatangani dapat diwakili oleh jenis bilangan bulat yang ditandatangani, maka jenis bilangan bulat yang tidak ditandatangani akan ditukar kepada jenis operan jenis integer yang ditandatangani.
  • Jika tidak, kedua-dua operan (misalnya char dan bool) akan ditukar menjadi jenis bilangan bulat yang tidak ditandatangani.

Promosi Titik Terapung

Jenis titik terapung termasuk "pelampung," "dua kali lipat", dan "panjang ganda."Jenis titik terapung harus mempunyai ketepatan sekurang-kurangnya sama dengan pendahulunya. Promosi titik terapung memungkinkan penukaran dari float menjadi double atau dari double menjadi double double.

Penukaran Penunjuk

Penunjuk dari satu jenis objek tidak dapat diberikan kepada penunjuk jenis objek yang berbeza. Kod berikut tidak akan menyusun:

int id = 6;
int * intPtr = &id;
float idf = 2.5;
float * floatPtr = &idf;
intPtr = floatPtr; // ralat di sini

Penunjuk nol adalah penunjuk yang nilai alamatnya adalah sifar. Penunjuk nol satu jenis objek tidak dapat ditugaskan ke penunjuk nol jenis objek yang berbeza. Kod berikut tidak akan menyusun:

int id = 6;
int * intPtr = &id;
intPtr = 0;
float idf = 2.5;
float * floatPtr = &idf;
floatPtr = 0;
intPtr = floatPtr; // ralat di sini

Kon penunjuk nol dari satu jenis objek tidak dapat diberikan kepada kon penunjuk nol dari jenis objek yang berbeza. Kod berikut tidak akan menyusun:

int id = 6;
int * intPtr = &id;
int * const intPC = 0;
float idf = 2.5;
float * floatPtr = &idf;
float * const floatPC = 0;
intPC = floatPC; // ralat di sini

Penunjuk nol boleh diberi nilai alamat yang berbeza untuk jenisnya. Kod berikut menggambarkan ini:

float idf = 2.5;
float * floatPtr = 0;
floatPtr = &idf;
cout<<*floatPtr<<'\n';

Keluarannya adalah 2.5.

Seperti yang dijangkakan, pemalar penunjuk nol tidak dapat diberikan nilai alamat dari jenisnya. Kod berikut tidak akan menyusun:

float idf = 2.5;
float * const floatPC = 0;
floatPC = &idf; // ralat di sini

Walau bagaimanapun, pemalar penunjuk nol dapat diberikan kepada penunjuk biasa, tetapi jenisnya sama (ini diharapkan). Kod berikut menggambarkan ini:

float idf = 2.5;
float * const floatPC = 0;
float * floatPter = &idf;
floatPter = floatPC; //OKEY
cout << floatPter << '\n';

Keluarannya adalah 0.

Dua nilai penunjuk kosong dari jenis yang sama membandingkan (==) sama.

Penunjuk ke jenis objek dapat ditugaskan ke penunjuk untuk dibatalkan. Kod berikut menggambarkan ini:

float idf = 2.5;
float * floatPtr = &idf;
batal * vd;
vd = floatPtr;

Kod itu disusun tanpa amaran atau mesej ralat.

Fungsi untuk Penukaran Penunjuk

Penunjuk ke fungsi yang tidak membuang pengecualian dapat ditugaskan ke penunjuk untuk berfungsi. Kod berikut menggambarkan ini:

#sertakan
menggunakan ruang nama std;
batal fn1 () kecuali

cout << "with noexcept" << '\n';

batal fn2 ()

// pernyataan

tidak sah (* func1) () kecuali;
tidak sah (* func2) ();
int utama ()

func1 = &fn1;
func2 = &fn2;
func2 = &fn1;
func2 ();
pulangan 0;

Keluarannya adalah dengan tidak terkecuali.

Penukaran Boolean

Dalam C ++, entiti yang dapat menghasilkan false termasuk "zero," "null pointer," dan "null member pointer."Semua entiti lain menghasilkan benar. Kod berikut menggambarkan ini:

bool a = 0.0; cout << a <<'\n';
float * floatPtr = 0;
bool b = floatPtr; cout << b <<'\n';
bool c = -2.5; cout << c <<'\n';
bool d = +2.5; cout << d <<'\n';

Keluarannya adalah:

0 // untuk palsu
0 // untuk palsu
1 // untuk benar
1 // untuk benar

Nilai, nilai dan nilai x

Pertimbangkan kod berikut:

int id = 35;
int & id1 = id;
cout << id1 << '\n';

Keluarannya adalah 35. Dalam kod, id dan id1 adalah nilai kerana mereka mengenal pasti lokasi (objek) dalam memori. Output 35 adalah nilai awal. Sebarang literal, kecuali literal string, adalah nilai prvalue. Nilai lain tidak begitu jelas, seperti dalam contoh berikut. Pertimbangkan kod berikut:

int id = 62;
int * ptr = &id;
int * pter;

Ptr adalah nilai kerana mengenal pasti lokasi (objek) dalam memori. Sebaliknya, pter bukan nilai. Pter adalah penunjuk, tetapi tidak mengenal pasti lokasi dalam memori (ia tidak menunjuk ke objek apa pun). Jadi, pter adalah nilai yang tinggi.

Pertimbangkan kod berikut:

batal fn ()

// pernyataan

tidak sah (* func) () = &fn;
terapung (* functn) ();

Fn () dan (* func) () adalah ungkapan lvalue kerana mereka mengenal pasti entiti (fungsi) dalam memori. Sebaliknya, (* functn) () bukan ungkapan lvalue. (* functn) () adalah penunjuk fungsi, tetapi tidak mengenal pasti entiti dalam memori (tidak menunjukkan fungsi dalam memori). Jadi, (* functn) () adalah ungkapan nilai.

Sekarang, pertimbangkan kod berikut:

struktur S

int n;
;
S obj;

S adalah kelas dan obj adalah objek yang ditunjukkan dari kelas. Obj mengenal pasti objek dalam ingatan. Kelas adalah unit umum. Jadi, S tidak benar-benar mengenal pasti objek dalam ingatan. S dikatakan sebagai objek yang tidak disebutkan namanya. S juga merupakan ungkapan nilai.

Fokus artikel ini adalah pada nilai. Prvalue bermaksud nilai murni.

Nilai X

Xvalue bermaksud Nilai Tamat. Nilai sementara adalah nilai luput. Nilai boleh menjadi nilai x. Prvalue juga boleh menjadi nilai x. Fokus artikel ini adalah pada nilai. Xvalue adalah rujukan lvalue atau rvalue yang tidak disebutkan namanya yang simpanannya dapat digunakan semula (biasanya kerana ia hampir habis hayatnya). Pertimbangkan kod berikut yang berfungsi:

struktur S

int n;
;
int q = S ().n;

Ungkapan "int q = S ().n; " menyalin apa sahaja nilai n yang ada pada q. S () hanyalah kaedah; itu bukan ungkapan yang biasa digunakan. S () adalah nilai yang penggunaannya telah menukarnya menjadi nilai x.

Penukaran Lvalue-to-rvalue

Pertimbangkan pernyataan berikut:

int ii = 70;

70 adalah prvalue (rvalue) dan ii adalah nilai. Sekarang, pertimbangkan kod berikut:

int ii = 70;
int tt = ii;

Dalam pernyataan kedua, ii berada dalam situasi nilai, jadi ii menjadi nilai di sana. Dengan kata lain, penyusun menukar ii menjadi nilai tersirat. Iaitu, ketika lvalue digunakan dalam situasi di mana implementasi mengharapkan prvalue, implementasi mengubah lvalue menjadi prvalue.

Penukaran Array-to-Pointer

Pertimbangkan kod berikut yang berfungsi:

char * p;
char q [] = 'a', 'b', 'c';
p = & q [0];
++p;
cout<<*p<<'\n';

Keluarannya adalah b. Pernyataan pertama adalah ungkapan dan penunjuk watak. Tetapi watak yang mana pernyataan itu menunjukkan? - Tiada watak. Jadi, ia adalah nilai dan bukan nilai. Pernyataan kedua adalah susunan di mana q [] adalah ungkapan lvalue. Pernyataan ketiga mengubah prvalue, p, menjadi ungkapan lvalue, yang menunjukkan elemen pertama dari array.

Penukaran Fungsi-ke-Penunjuk

Pertimbangkan program berikut:

#sertakan
menggunakan ruang nama std;
tidak sah (* func) ();
batal fn ()

// pernyataan

int utama ()

func = &fn;
pulangan 0;

Ungkapan "void (* func) ();" adalah penunjuk kepada fungsi. Tetapi fungsi mana yang menunjukkan ungkapan? - Tiada fungsi. Jadi, ia adalah nilai dan bukan nilai. Fn () adalah definisi fungsi, di mana fn adalah ungkapan nilai. Dalam utama (), “func = &fn;"Mengubah prvalue, func, menjadi ungkapan lvalue yang menunjukkan fungsi, fn ().

Penukaran Pemanfaatan Sementara

Dalam C ++, nilai boleh ditukar menjadi nilai x dari jenis yang sama. Kod berikut menggambarkan ini:

struktur S

int n;
;
int q = S ().n;

Di sini, nilai, S (), telah ditukar menjadi nilai x. Sebagai nilai x, ia tidak akan bertahan lama - lihat penjelasan lebih lanjut di atas.

Penukaran Kelayakan

Jenis yang memenuhi syarat cv adalah jenis yang memenuhi syarat oleh kata terpelihara, "const", dan / atau kata yang dicadangkan, "tidak stabil."

Kelayakan Cv juga diperingkat. Tidak ada kualifikasi cv yang kurang dari kualifikasi “const”, yang lebih rendah daripada kualifikasi “const volatile”. Tidak ada kualifikasi cv yang kurang dari kualifikasi "tidak stabil", yang kurang dari kualifikasi "const volatile". Jadi, terdapat dua aliran peringkat kelayakan. Satu jenis boleh lebih berkualiti daripada yang lain.

Jenis prvalue cv-prvalue yang lebih rendah boleh ditukar menjadi jenis prvalue yang lebih berkualiti cv. Kedua-dua jenis mestilah pointer-to-cv.

Kesimpulannya

Entiti C ++ boleh ditukar dari satu jenis ke jenis yang berkaitan secara tersirat atau tersurat. Walau bagaimanapun, pengaturcara mesti memahami apa yang boleh ditukar dan apa yang tidak dapat ditukarkan, dan ke dalam bentuk apa. Penukaran boleh berlaku dalam domain berikut: Penukaran Integral, Penukaran Titik Terapung, Penukaran Integral Terapung, Penukaran Aritmetik Biasa, Penukaran Pointer, Fungsi ke Penukaran Pointer, Penukaran Boolean, Penukaran Nilai-ke-Nilai, Penukaran Array-ke-Pointer , Penukaran Function-to-Pointer, Penukaran Materialisasi Sementara, dan Penukaran Kelayakan.

Aplikasi Pemetaan Gamepad Terbaik untuk Linux
Sekiranya anda suka bermain permainan di Linux dengan gamepad dan bukannya sistem input papan kekunci dan tetikus biasa, ada beberapa aplikasi berguna...
Alat Berguna untuk Pemain Linux
Sekiranya anda suka bermain permainan di Linux, kemungkinan anda telah menggunakan aplikasi dan utiliti seperti Wine, Lutris dan OBS Studio untuk meni...
HD Remastered Games untuk Linux yang Tidak Pernah Melancarkan Linux Sebelumnya
Banyak pembangun dan penerbit permainan hadir dengan penghapus HD permainan lama untuk memperpanjang usia francais, harap peminat meminta keserasian d...