C++

Konversi Standar C++

Konversi Standar C++
Ada dua tipe entitas dalam C++, tipe fundamental dan tipe gabungan. Tipe dasar adalah tipe skalar. Tipe gabungan adalah tipe entitas lainnya. Konversi dapat terjadi dari satu tipe entitas ke tipe lain yang sesuai. Perhatikan program berikut:

#termasuk
#termasuk
menggunakan namespace std;
int utama()

int rt1 = kuadrat(5);
int rt2 = kuadrat(8);
cout<kembali 0;

Keluarannya adalah 2, 2, artinya program telah mengembalikan akar kuadrat dari 5 sebagai 2 dan akar kuadrat dari 8 juga sebagai 2. Jadi, dua pernyataan pertama dalam utama() fungsi telah menentukan jawaban dari akar kuadrat dari 5 dan akar kuadrat dari 8. Artikel ini tidak membahas lantai atau langit-langit di C++. Sebaliknya, artikel ini membahas konversi satu tipe C++ ke tipe C++ lain yang sesuai; menunjukkan perkiraan apa pun dalam nilai yang dibuat, kehilangan presisi, atau kendala yang ditambahkan atau dihapus. Pengetahuan dasar C++ adalah prasyarat untuk memahami artikel ini.

Isi Artikel

  • Konversi Integral
  • Konversi Titik Mengambang
  • Konversi Mengambang-Integral
  • Peringkat Konversi Bilangan Bulat
  • Promosi Integral
  • Konversi Aritmatika Biasa
  • Promosi Titik Mengambang
  • Konversi Pointer
  • Konversi Fungsi ke Pointer
  • Konversi Boolean
  • Nilai, nilai, dan nilai x
  • Nilai X
  • Konversi Nilai-ke-nilai
  • Konversi Array-ke-Pointer
  • Konversi Fungsi ke Pointer
  • Konversi Materialisasi Sementara
  • Konversi Kualifikasi
  • Kesimpulan

Konversi Integral

Konversi integral adalah konversi bilangan bulat. Bilangan bulat yang tidak ditandatangani termasuk “unsigned char,” “unsigned short int,” “unsigned int,” “unsigned long int,” dan “unsigned long int.” Bilangan bulat bertanda yang sesuai termasuk “char bertanda”, “short int”, “int”, “long int”, dan “long long int”.”Setiap tipe int harus disimpan dalam byte sebanyak pendahulunya. Untuk sebagian besar sistem, satu tipe entitas dapat dikonversi ke tipe yang sesuai tanpa masalah. Masalah terjadi saat mengonversi dari tipe rentang yang lebih besar ke tipe rentang yang lebih kecil, atau saat mengonversi nomor bertanda ke nomor tak bertanda yang sesuai.

Setiap kompiler memiliki nilai maksimum yang dapat diambil untuk int pendek. Jika angka yang lebih tinggi dari maksimum itu, dimaksudkan untuk int, ditugaskan ke int pendek, kompiler akan mengikuti beberapa algoritma dan mengembalikan angka dalam kisaran int pendek. Jika pemrogram beruntung, kompiler akan memperingatkan masalah dengan menggunakan konversi yang tidak tepat. Penjelasan yang sama berlaku untuk konversi tipe int lainnya.

Pengguna harus berkonsultasi dengan dokumentasi kompiler untuk menentukan nilai pembatas untuk setiap jenis entitas.

Jika nomor int pendek bertanda negatif akan diubah menjadi nomor int pendek yang tidak ditandatangani, kompiler akan mengikuti beberapa algoritma dan mengembalikan angka positif dalam kisaran int pendek yang tidak ditandatangani. Konversi semacam ini harus dihindari. Penjelasan yang sama berlaku untuk konversi tipe int lainnya.

Setiap bilangan bulat, kecuali 0, dapat dikonversi ke Boolean true. 0 dikonversi ke Boolean salah. Kode berikut menggambarkan hal ini:

int = -27647;
mengapung b = 2.5;
intc = 0;
bool a1 = a;
bool b1 = b;
bool c1 = c;
cout<cout<cout<Outputnya adalah:

1 untuk benar
1 untuk benar
0 untuk salah

Konversi Titik Mengambang

Tipe floating-point termasuk “float”, “double”, dan “long double”.”Tipe titik-mengambang tidak dikelompokkan menjadi ditandatangani dan tidak ditandatangani, seperti bilangan bulat. Setiap jenis dapat memiliki nomor yang ditandatangani atau tidak ditandatangani. Tipe floating-point setidaknya harus memiliki presisi yang sama dengan pendahulunya. Artinya, "ganda panjang" harus memiliki presisi yang sama atau lebih besar untuk "ganda", dan "ganda" harus memiliki presisi yang sama atau lebih besar untuk "mengambang".”

Ingat bahwa rentang tipe floating-point tidak kontinu; alih-alih, itu dalam langkah-langkah kecil. Semakin besar presisi jenisnya, semakin kecil langkahnya, dan semakin besar jumlah byte untuk menyimpan nomornya. Jadi, ketika angka floating-point diubah dari tipe presisi yang lebih rendah ke tipe presisi yang lebih tinggi, programmer harus menerima peningkatan presisi yang salah dan kemungkinan peningkatan jumlah byte untuk penyimpanan angka. Ketika angka floating-point diubah dari tipe presisi yang lebih tinggi ke tipe presisi yang lebih rendah, programmer harus menerima kerugian dalam presisi. Jika jumlah byte untuk penyimpanan angka harus dikurangi, maka kompiler akan mengikuti beberapa algoritma dan mengembalikan angka sebagai pengganti (yang mungkin bukan yang diinginkan programmer). Juga, ingatlah masalah di luar jangkauan.

Konversi Terapung-Integral

Angka titik-mengambang diubah menjadi bilangan bulat dengan memotong bagian pecahan. Kode berikut menggambarkan hal ini:

mengapung f = 56.953;
int saya = f;
cout<Keluarannya adalah 56. Rentang untuk float dan integer harus kompatibel.

Ketika integer diubah menjadi float, nilai yang ditampilkan sebagai float sama dengan yang diketik sebagai integer. Namun, ekuivalen float mungkin merupakan nilai yang tepat atau memiliki sedikit perbedaan fraksional yang tidak ditampilkan. Alasan perbedaan fraksional adalah bahwa bilangan titik-mengambang direpresentasikan di komputer dalam langkah-langkah pecahan kecil, dan dengan demikian mewakili bilangan bulat secara tepat akan menjadi kebetulan. Jadi, meskipun bilangan bulat yang ditampilkan sebagai float sama dengan yang diketik, tampilan mungkin merupakan perkiraan dari apa yang disimpan.

Peringkat Konversi Bilangan Bulat

Setiap tipe bilangan bulat memiliki peringkat yang telah diberikan padanya. Peringkat ini membantu dalam konversi. Peringkat itu relatif; peringkatnya tidak pada level tetap. Kecuali untuk char dan char yang ditandatangani, tidak ada dua bilangan bulat yang ditandatangani memiliki peringkat yang sama (dengan asumsi bahwa char ditandatangani). Jenis bilangan bulat tidak bertanda memiliki peringkat yang sama dengan jenis bilangan bulat bertanda yang sesuai. Peringkatnya adalah sebagai berikut:

  • Dengan asumsi bahwa char ditandatangani, maka char dan char yang ditandatangani memiliki peringkat yang sama.
  • Pangkat tipe integer bertanda lebih besar daripada peringkat tipe integer bertanda dengan jumlah byte penyimpanan yang lebih kecil. Jadi, peringkat ditandatangani long long int lebih besar dari peringkat ditandatangani panjang int, yang lebih besar dari peringkat ditandatangani int, yang lebih besar dari peringkat ditandatangani pendek int, yang lebih besar dari peringkat char ditandatangani.
  • Pangkat dari tipe integer yang tidak ditandatangani sama dengan peringkat dari tipe integer bertanda yang sesuai.
  • Pangkat unsigned char sama dengan pangkat char yang ditandatangani.
  • bool memiliki peringkat paling sedikit; peringkatnya kurang dari karakter yang ditandatangani.
  • char16_t memiliki peringkat yang sama dengan int pendek. char32_t memiliki peringkat yang sama dengan int. Untuk kompiler g++, wchar_t memiliki peringkat yang sama dengan int.

Promosi Integral

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

  • Int pendek yang ditandatangani (dua byte) dapat dikonversi menjadi int yang ditandatangani (empat byte). Int pendek yang tidak ditandatangani (dua byte) dapat dikonversi menjadi int yang tidak ditandatangani (empat byte). Catatan: mengonversi short int ke long int atau long long int menyebabkan pemborosan penyimpanan (lokasi objek) byte dan pemborosan memori. Bool, char16_t, char32_t, dan wchar_t dikecualikan dari promosi ini (dengan kompiler g++, char32_t dan wchar_t memiliki jumlah byte yang sama).
  • Dengan kompiler g++, tipe char16_t dapat dikonversi ke tipe int yang ditandatangani atau tipe int yang tidak ditandatangani; tipe char32_t dapat dikonversi ke tipe int yang ditandatangani atau tipe int yang tidak ditandatangani; dan tipe wchar_t dapat dikonversi ke tipe int yang ditandatangani atau tidak ditandatangani.
  • Tipe bool dapat dikonversi menjadi tipe int. Dalam hal ini, true menjadi 1 (empat byte) dan false menjadi 0 (empat byte). Int dapat ditandatangani atau ditandatangani.
  • Promosi bilangan bulat juga ada untuk jenis enumerasi tidak tercakup - lihat nanti.

Konversi Aritmatika Biasa

Perhatikan kode berikut:

mengapung f = 2.5;
int saya = f;
cout<Kode dikompilasi tanpa menunjukkan peringatan atau kesalahan apa pun, memberikan output dari 2, yang mungkin tidak seperti yang diharapkan. = adalah operator biner karena membutuhkan operan kiri dan kanan. Perhatikan kode berikut:

int i1 = 7;
int i2 = 2;
float flt = i1 / i2;
cout<Keluarannya adalah 3, tapi ini salah; itu seharusnya 3.5. Operator pembagian, /, juga merupakan operator biner.

C++ memiliki konversi aritmatika biasa yang harus diketahui programmer untuk menghindari kesalahan dalam pengkodean. Konversi aritmatika yang biasa dilakukan pada operator biner adalah sebagai berikut:

  • Jika salah satu operan bertipe “long double”, maka operan lainnya akan dikonversi menjadi long double.
  • Lain, jika salah satu operan ganda, yang lain akan dikonversi menjadi ganda.
  • Lain, jika salah satu operan adalah float, yang lain akan dikonversi menjadi float. Pada kode di atas, hasil i1/i2 secara resmi adalah 2; itu sebabnya flt adalah 2. Hasil biner, /, diterapkan sebagai operan kanan ke operator biner, =. Jadi, nilai akhir dari 2 adalah float (bukan int).

LAINNYA, PROMOSI INTEGER AKAN TERJADI SEBAGAI BERIKUT:

  • Jika kedua operan memiliki tipe yang sama, maka tidak ada konversi lebih lanjut yang terjadi.
  • Selain itu, jika kedua operan bertipe integer bertanda atau keduanya bertipe integer tak bertanda, maka operan dengan rangking integer yang lebih rendah akan dikonversi ke tipe operan dengan rangking yang lebih tinggi.
  • Lain, jika satu operan ditandatangani dan yang lain tidak ditandatangani, dan jika jenis operan yang tidak ditandatangani lebih besar dari atau sama dengan peringkat dari jenis operan yang ditandatangani, dan jika nilai operan yang ditandatangani lebih besar dari atau sama dengan nol, maka operan yang ditandatangani akan dikonversi ke jenis operan yang tidak ditandatangani (dengan mempertimbangkan rentang). Jika operan yang ditandatangani adalah negatif, maka kompiler akan mengikuti algoritma dan mengembalikan angka yang mungkin tidak dapat diterima oleh programmer.
  • Lain, jika satu operan adalah tipe integer yang ditandatangani dan yang lainnya adalah tipe integer yang tidak ditandatangani, dan jika semua nilai yang mungkin dari tipe operan dengan tipe integer yang tidak ditandatangani dapat diwakili oleh tipe integer yang ditandatangani, maka tipe integer yang tidak ditandatangani akan dikonversi ke jenis operan dari tipe integer yang ditandatangani.
  • Lain, dua operan (char dan bool, misalnya) akan dikonversi ke tipe integer unsigned.

Promosi Titik Mengambang

Tipe floating-point termasuk “float”, “double”, dan “long double”.Tipe titik-mengambang setidaknya harus memiliki presisi yang sama dengan pendahulunya. Promosi floating-point memungkinkan konversi dari float ke double atau dari double ke long double.

Konversi Pointer

Pointer dari satu tipe objek tidak dapat ditetapkan ke pointer dari tipe objek yang berbeda. Kode berikut tidak akan dikompilasi:

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

Pointer null adalah pointer yang nilai alamatnya nol. Pointer null dari satu tipe objek tidak dapat ditetapkan ke pointer null dari tipe objek yang berbeda. Kode berikut tidak akan dikompilasi:

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

Const pointer nol dari satu tipe objek tidak dapat ditetapkan ke const pointer nol dari tipe objek yang berbeda. Kode berikut tidak akan dikompilasi:

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

Pointer nol dapat diberikan nilai alamat yang berbeda untuk tipenya. Kode berikut menggambarkan hal ini:

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

Keluarannya adalah 2.5.

Seperti yang diharapkan, konstanta penunjuk nol tidak dapat diberikan nilai alamat apa pun dari jenisnya. Kode berikut tidak akan dikompilasi:

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

Namun, konstanta penunjuk nol dapat ditetapkan ke penunjuk biasa, tetapi dengan tipe yang sama (ini yang diharapkan). Kode berikut menggambarkan hal ini:

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

Keluarannya adalah 0.

Dua nilai pointer nol dari tipe yang sama membandingkan (==) sama.

Pointer ke tipe objek dapat ditetapkan ke pointer ke void. Kode berikut menggambarkan hal ini:

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

Kode dikompilasi tanpa peringatan atau pesan kesalahan.

Konversi Fungsi ke Pointer

Pointer ke fungsi yang tidak akan mengeluarkan pengecualian dapat ditugaskan ke pointer ke fungsi. Kode berikut menggambarkan hal ini:

#termasuk
menggunakan namespace std;
batal fn1() tidak kecuali

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

batal fn2()

//pernyataan

void (* func1)() tidak ada kecuali;
batal (*fungsi2)();
int utama()

fungsi1 = &fn1;
fungsi2 = &fn2;
fungsi2 = &fn1;
fungsi2();
kembali 0;

Keluarannya adalah tanpa kecuali.

Konversi Boolean

Di C++, entitas yang dapat menghasilkan false termasuk "nol," "pointer null," dan "pointer anggota null.”Semua entitas lain menghasilkan true. Kode berikut menggambarkan hal ini:

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

Outputnya adalah:

0 //untuk salah
0 //untuk salah
1 //untuk benar
1 //untuk benar

Nilai, nilai, dan nilai x

Perhatikan kode berikut:

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

Keluarannya adalah 35. Dalam kode, id dan id1 adalah nilai karena mereka mengidentifikasi lokasi (objek) di memori. Output 35 adalah prvalue. Setiap literal, kecuali string literal, adalah prvalue. Nilai-nilai lain tidak begitu jelas, seperti pada contoh-contoh berikut:. Perhatikan kode berikut:

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

Ptr adalah nilai karena mengidentifikasi lokasi (objek) dalam memori. Di sisi lain, pter bukan nilai. Pter adalah pointer, tetapi tidak mengidentifikasi lokasi mana pun di memori (tidak menunjuk ke objek apa pun). Jadi, pter adalah nilai.

Perhatikan kode berikut:

batal fn()

//pernyataan

batal (*fungsi)() = &fn;
float (*fungsin)();

Fn() dan (*func)() adalah ekspresi nilai karena mereka mengidentifikasi entitas (fungsi) dalam memori. Di sisi lain, (* functn)() bukan ekspresi nilai. (* functn)() adalah penunjuk ke suatu fungsi, tetapi tidak mengidentifikasi entitas apa pun di memori (tidak menunjuk ke fungsi apa pun di memori). Jadi, (* functn)() adalah ekspresi nilai.

Sekarang, perhatikan kode berikut:

struktur S

int n;
;
S obj;

S adalah kelas dan obj adalah objek yang diturunkan dari kelas. Obj mengidentifikasi objek dalam memori. Kelas adalah unit umum general. Jadi, S tidak benar-benar mengidentifikasi objek apa pun dalam memori. S dikatakan sebagai objek yang tidak disebutkan namanya. S juga merupakan ekspresi nilai.

Fokus artikel ini adalah pada nilai-nilai. Prvalue berarti nilai murni.

Nilai X

Xvalue adalah singkatan dari Expiring Value. Nilai sementara adalah nilai yang kedaluwarsa. Nilai bisa menjadi nilai x. Sebuah prvalue juga bisa menjadi xvalue. Fokus artikel ini adalah pada nilai-nilai. Nilai x adalah nilai atau referensi nilai tanpa nama yang penyimpanannya dapat digunakan kembali (biasanya karena mendekati akhir masa pakainya). Pertimbangkan kode berikut yang berfungsi:

struktur S

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

Ekspresi “int q = S().t;” menyalin nilai apa pun yang dimiliki n ke q. S() hanyalah sarana; itu bukan ekspresi yang biasa digunakan. S() adalah nilai yang penggunaannya telah mengubahnya menjadi nilai x.

Konversi Nilai-ke-nilai

Perhatikan pernyataan berikut:

int ii = 70;

70 adalah nilai awal (nilai) dan ii adalah nilai. Sekarang, perhatikan kode berikut:

int ii = 70;
int tt = ii;

Dalam pernyataan kedua, ii berada dalam situasi prvalue, jadi ii menjadi prvalue di sana. Dengan kata lain, kompiler mengonversi ii menjadi nilai awal secara implisit. Yaitu, ketika nilai digunakan dalam situasi di mana implementasi mengharapkan nilai awal, implementasi mengubah nilai menjadi nilai awal.

Konversi Array-ke-Pointer

Pertimbangkan kode berikut yang berfungsi:

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

Keluarannya adalah b. Pernyataan pertama adalah ekspresi dan merupakan penunjuk ke karakter. Tapi ke karakter mana pernyataan itu menunjuk? - Tidak ada karakter. Jadi, ini adalah prvalue dan bukan lvalue. Pernyataan kedua adalah array di mana q[] adalah ekspresi nilai. Pernyataan ketiga mengubah prvalue, p, menjadi ekspresi lvalue, yang menunjuk ke elemen pertama dari array.

Konversi Fungsi ke Pointer

Perhatikan program berikut:

#termasuk
menggunakan namespace std;
batal (*fungsi)();
batal fn()

//pernyataan

int utama()

fungsi = &fn;
kembali 0;

Ekspresi “void (* func)();” adalah penunjuk ke fungsi. Tetapi ke fungsi mana ekspresi itu menunjuk? - Tidak ada fungsi. Jadi, ini adalah prvalue dan bukan lvalue. Fn() adalah definisi fungsi, di mana fn adalah ekspresi nilai. Di main(), “fungsi = &fn;” mengubah prvalue, func, menjadi ekspresi lvalue yang menunjuk ke fungsi, fn().

Konversi Materialisasi Sementara

Dalam C++, nilai awal dapat dikonversi ke nilai x dengan tipe yang sama. Kode berikut menggambarkan hal ini:

struktur S

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

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

Konversi Kualifikasi

Tipe berkualifikasi cv adalah tipe yang dikualifikasikan oleh kata yang dicadangkan, “const,” dan/atau kata yang dicadangkan, “volatile.”

Kualifikasi Cv juga diperingkat. Tidak ada kualifikasi cv yang kurang dari kualifikasi "const", yang kurang dari kualifikasi "const volatile". Tidak ada kualifikasi cv yang kurang dari kualifikasi "volatile", yang kurang dari kualifikasi "const volatile". Jadi, ada dua aliran peringkat kualifikasi. Satu jenis bisa lebih memenuhi syarat cv daripada yang lain.

Tipe berkualifikasi cv dengan nilai lebih rendah dapat dikonversi ke tipe berkualifikasi cv yang lebih berkualifikasi. Kedua tipe harus pointer-to-cv.

Kesimpulan

Entitas C++ dapat dikonversi dari satu tipe ke tipe terkait secara implisit atau eksplisit. Namun, programmer harus memahami apa yang dapat diubah dan apa yang tidak dapat diubah, dan menjadi bentuk apa. Konversi dapat terjadi dalam domain berikut: Konversi Integral, Konversi Titik Mengambang, Konversi Integral Mengambang, Konversi Aritmatika Biasa, Konversi Pointer, Konversi Fungsi ke Pointer, Konversi Boolean, Konversi Lnilai ke Nilai, Konversi Array ke Pointer , Konversi Fungsi ke Pointer, Konversi Materialisasi Sementara, dan Konversi Kualifikasi.

Cara mengubah penunjuk Mouse dan ukuran kursor, warna & skema pada Windows 10
Penunjuk mouse dan kursor di Windows 10 adalah aspek yang sangat penting dari sistem operasi. Ini dapat dikatakan untuk sistem operasi lain juga, jadi...
Mesin Game Gratis dan Sumber Terbuka untuk Mengembangkan Game Linux
Artikel ini akan membahas daftar mesin game sumber terbuka dan gratis yang dapat digunakan untuk mengembangkan game 2D dan 3D di Linux. Ada banyak mes...
Shadow of the Tomb Raider untuk Tutorial Linux
Shadow of the Tomb Raider adalah tambahan kedua belas untuk seri Tomb Raider - waralaba game aksi-petualangan yang dibuat oleh Eidos Montreal. Permain...