Video: Python Tutorial for Beginners [Full Course] Learn Python for Web Development 2024
Oleh Stephen R. Davis
C ++ bukanlah bahasa pemrograman yang mudah untuk dikuasai. Hanya melalui pengalaman akan segudang kombinasi simbol mulai tampak alami bagi Anda. Lembar Cheat ini, bagaimanapun, memberi Anda beberapa tip bagus untuk meringankan transisi dari C ++ ke C + + guru: Tahu cara membaca ekspresi C ++ yang rumit; belajar bagaimana menghindari masalah pointer; dan mencari tahu bagaimana dan kapan harus membuat salinan dalam.
Cara Membaca Ekspresi C ++ Kompleks
C ++ penuh dengan simbol kecil, yang masing-masing menambahkan makna ekspresi. Aturan tata bahasa C ++ begitu fleksibel sehingga simbol-simbol ini dapat digabungkan dalam kombinasi yang hampir tak tertembus. Ekspresi dalam bahasa C yang sederhana bisa jadi sangat bodoh sehingga dulu ada kontes tahunan untuk siapa yang bisa menulis program yang paling tidak jelas dan siapa yang bisa memahaminya.
Tidak ada ide bagus untuk mencoba menulis kode yang rumit tapi kadang Anda akan menemukan ekspresi di C ++ yang agak membingungkan pada pandangan pertama. Cukup gunakan langkah-langkah berikut untuk menemukannya:
-
Mulai dari kurung yang paling banyak disematkan.
Mulailah mencari kurung paling luar. Di dalam mereka, cari kurung yang disisipkan. Ulangi prosesnya sampai Anda berhasil mencapai pasangan tanda kurung terdalam. Mulai evaluasi subexpression yang pertama dengan menggunakan aturan berikut. Begitu Anda memahami ungkapan itu, kembalilah ke tingkat berikutnya dan ulangi prosesnya.
-
Di dalam sepasang tanda kurung, evaluasi setiap operasi sesuai urutan sebelumnya.
Perintah yang dievaluasi operator ditentukan oleh prioritas operator yang ditunjukkan pada tabel. Indirection datang sebelum perkalian yang datang sebelum penambahan sehingga berikut ini menambahkan 1 ditambah 2 kali nilai yang ditunjukkan oleh * ptr.
int i = 1 + 2 * * ptr;
Diawal | Operator | Arti |
---|---|---|
1 | () (unary) | Tuliskan fungsi |
2 | * dan -> unary) | Dereference a pointer |
2 | - (unary) | Mengembalikan argumen negatifnya |
3 | ++ (unary) | Kenaikan |
3 > - (unary) | Pengurangan | 4 |
* (biner) | Perkalian | 4 |
/ (biner) | Divisi | 4 |
% (biner) | Modulo | 5 |
+ (biner) | Penambahan | 5 |
- (biner) | Pengurangan | 6 |
&& (biner) | Logika DAN | 6 |
! ! | Mengenal operasi dari prioritas yang sama dari kiri ke kanan (kecuali tugas, yang pergi ke arah lain). | Sebagian besar operator dengan prioritas yang sama mengevaluasi dari kiri ke kanan. Dengan demikian, berikut ini menambahkan 1 sampai 2 dan menambahkan hasilnya ke 3: |
int i = 1 + 2 + 3; | Urutan evaluasi beberapa operator tidak masalah. Misalnya, selain bekerja sama dari kiri ke kanan seperti halnya dari kanan ke kiri. Urutan evaluasi membuat banyak perbedaan untuk beberapa operasi seperti pembagian. Berikut ini membagi 8 dengan 4 dan membagi hasilnya dengan 2: | int i = 8/4/2; |
-
Pengecualian utama terhadap peraturan ini adalah penugasan, yang dievaluasi dari kanan ke kiri:
a = b = c;
Ini menetapkan c ke b dan hasilnya ke a.
Evaluasi subexpressions tanpa urutan tertentu.
Perhatikan ungkapan berikut:
int i = f () + g () * h ();
Perkalian memiliki preseden yang lebih tinggi, jadi Anda mungkin berasumsi bahwa fungsi g () dan h () dipanggil sebelum f (), namun, ini bukan masalahnya. Fungsi panggilan memiliki prioritas tertinggi dari semuanya, jadi ketiga fungsi tersebut disebut sebelum perkalian atau penambahan dilakukan. (Hasil kembali dari g () dan h () dikalikan dan kemudian ditambahkan ke hasil yang dikembalikan dari f ().
Satu-satunya saat urutan fungsi itu disebut membuat perbedaan adalah ketika fungsi memiliki efek samping. seperti membuka file atau mengubah nilai variabel global. Anda pasti tidak akan menulis program Anda sehingga mereka bergantung pada jenis efek samping ini.
-
Lakukan semua jenis konversi hanya jika diperlukan.
Anda seharusnya tidak membuat lebih banyak jenis konversi daripada yang benar-benar diperlukan. Misalnya, ekspresi berikut memiliki setidaknya tiga dan mungkin empat jenis konversi:
float f = 'a' + 1;
char 'a' harus dipromosikan ke int untuk melakukan penambahan. Int kemudian dikonversi menjadi double dan kemudian turun dikonversi menjadi float presisi tunggal. Ingat bahwa semua aritmatika dilakukan baik dalam int atau double. Anda umumnya harus menghindari melakukan aritmatika pada tipe karakter dan hindari pengapungan presisi tunggal sama sekali.
5 Cara Menghindari Masalah Pointer di C ++
-
Di C ++, pointer
adalah variabel yang berisi alamat objek di memori internal komputer. Gunakan langkah-langkah ini untuk menghindari masalah dengan petunjuk di C ++:
Inisialisasi pointer saat dideklarasikan.
Jangan pernah meninggalkan variabel pointer yang tidak diinisiasi - hal-hal tidak akan terlalu buruk jika pointer yang tidak diinisiasi selalu berisi nilai acak - sebagian besar nilai acak adalah nilai pointer ilegal dan akan menyebabkan program mogok begitu penggunaannya. Masalahnya adalah bahwa variabel yang tidak diinisiasi cenderung mengambil nilai variabel pointer lain yang sebelumnya digunakan. Masalah ini sangat sulit untuk debug.
Jika Anda tidak tahu apa lagi untuk menginisialisasi pointer ke, inisialisasi ke nullptr. nullptr dijamin menjadi alamat ilegal Nol keluar petunjuk setelah Anda menggunakannya. Demikian pula, selalu nol sebuah variabel pointer setelah pointer tidak lagi valid dengan menugaskannya nilai nullptr. Hal ini terutama terjadi ketika Anda mengembalikan satu blok memori ke tumpukan dengan menggunakan hapus; selalu nol pointer setelah kembali tumpukan memori.
-
Alokasikan memori dari tumpukan dan kembalikan ke tumpukan di "tingkat" yang sama untuk menghindari kebocoran memori.
Selalu coba untuk mengembalikan blok memori ke tumpukan pada tingkat abstraksi yang sama dengan saat Anda mengalokasikannya. Ini umumnya berarti mencoba untuk menghapus memori pada tingkat panggilan fungsi yang sama.
Catch pengecualian untuk menghapus memori bila perlu.
-
Jangan lupa bahwa pengecualian dapat terjadi hampir setiap saat. Jika Anda berniat untuk menangkap pengecualian dan terus beroperasi (sebagai lawan membiarkan program crash), pastikan bahwa Anda menangkap pengecualian dan mengembalikan blok memori ke tumpukan sebelum petunjuk yang mengarah ke mereka keluar dari ruang lingkup dan memori adalah kalah.
Pastikan jenisnya sesuai.
-
Selalu pastikan jenis pointer sesuai dengan tipe yang dibutuhkan. Jangan recast pointer tanpa alasan tertentu. Perhatikan hal berikut:
void fn (int * p); void myFunc () {char c = 'a'; char * pC = & c; fn ((int *) pC);}
-
Fungsi di atas dikompilasi tanpa keluhan karena pointer karakter pC telah direkonstruksi ke int * agar sesuai dengan deklarasi fn (int *); Namun, program ini hampir pasti tidak akan berhasil. Fungsi fn () mengharapkan pointer ke bilangan bulat 32-bit penuh dan bukan karakter rinky-dink 8 bit char. Jenis masalah ini sangat sulit dipilah.
Bagaimana dan Kapan Membuat Salinan dalam Kelas C ++
-
yang mengalokasikan sumber daya di konstruktor mereka biasanya harus menyertakan konstruktor salinan untuk membuat salinan dari sumber daya ini. Mengalokasikan blok memori baru dan menyalin isi dokumen asli ke dalam blok baru ini dikenal dengan membuat
deep copy
(berlawanan dengan salinan dangkal default). Gunakan langkah-langkah berikut untuk menentukan bagaimana dan kapan harus membuat salinan dalam C ++:
Selalu buat salinan dalam jika konstruktor mengalokasikan sumber daya.
Secara default, C ++ membuat apa yang disebut "dangkal" salinan anggota-oleh-anggota objek saat mengirimkannya ke fungsi atau sebagai hasil sebuah tugas. Anda harus mengganti operator salin dangkal default dengan salinan dalamnya setara untuk kelas yang mengalokasikan sumber daya di konstruktor. Sumber daya paling umum yang dialokasikan adalah memori tumpukan yang dikembalikan oleh operator baru.
Selalu sertakan penghancur untuk kelas yang mengalokasikan sumber daya. Jika Anda membuat konstruktor yang mengalokasikan sumber daya, Anda harus membuat penghancur yang mengembalikannya. Tidak ada pengecualian. Selalu mendeklarasikan destructor virtual.
-
Kesalahan pemula yang umum adalah lupa mendeklarasikan destruktor Anda secara virtual. Program akan berjalan baik sampai beberapa programmer yang tidak curiga datang dan mewarisi dari kelas Anda. Program ini masih tampak berhasil, namun karena destruktor di kelas dasar tidak dapat dipanggil dengan benar, kebocoran memori dari program Anda seperti saringan sampai akhirnya mogok. Masalah ini sulit ditemukan.
Selalu sertakan konstruktor salin untuk kelas yang mengalokasikan sumber daya.
-
Konstruktor copy membuat salinan objek yang tepat saat ini dengan mengalokasikan memori dari tumpukan dan menyalin isi objek sumber.
Selalu timpa operator penugasan untuk kelas yang mengalokasikan sumber daya.
-
Pemrogram harus berkecil hati karena mengesampingkan operator, namun operator penugasan adalah pengecualian. Anda harus mengganti operator penugasan untuk kelas yang mengalokasikan sumber daya di konstruktor.
Operator penugasan harus melakukan tiga hal:
-
Pastikan benda kiri dan kanan bukan obyek yang sama. Dengan kata lain, pastikan programmer aplikasi tidak menulis sesuatu seperti (a = a). Jika mereka, tidak melakukan apapun.
Ajukan kode yang sama seperti destruktor pada objek tangan kiri untuk mengembalikan sumber dayanya.
-
Ajukan kode yang sama dengan konstruktor salin untuk membuat salinan dalam objek tangan kanan ke objek tangan kiri.
Jika Anda tidak dapat melakukan itu, maka hapuslah konstruktor salinan dan operator penugasan sehingga program tidak dapat membuat salinan dari objek Anda.
Jika Anda bahkan tidak dapat melakukannya karena kompiler Anda tidak mendukung fitur konstruktor hapus C ++ 2011, buatlah konstruktor dan operator salin kosong dan nyatakan mereka dilindungi agar kelas lain tidak menggunakannya.