Video: Technology Stacks - Computer Science for Business Leaders 2016 2024
Oleh Stephen R. Davis
C ++ bukan bahasa pengaturcaraan mudah untuk menguasai. Hanya melalui pengalaman akan pelbagai kombinasi simbol mula kelihatan semula jadi kepada anda. Lembaran Menipu ini, bagaimanapun, memberi anda beberapa petua yang kukuh untuk mengurangkan peralihan dari pemula C ++ ke guru C ++: Ketahui cara membaca ungkapan C ++ yang rumit; belajar bagaimana untuk mengelakkan masalah penunjuk; dan mengetahui bagaimana dan bila membuat salinan dalam.
Cara Membaca Kompleks C ++ Expression
C ++ penuh dengan simbol-simbol kecil, masing-masing menambah makna ungkapan. Peraturan tata bahasa C ++ sangat fleksibel sehingga simbol-simbol ini dapat digabungkan dalam kombinasi yang hampir tidak dapat ditembusi. Ungkapan dalam bahasa C yang lebih mudah dapat menjadi sangat bodoh sehingga dulu ada pertandingan tahunan untuk siapa yang dapat menulis program yang paling tidak jelas dan siapa yang dapat memahaminya.
Ia bukan idea yang baik untuk cuba menulis kod kompleks tetapi kadang-kadang anda akan melangkaui ekspresi dalam C ++ yang sedikit membingungkan pada pandangan pertama. Hanya gunakan langkah-langkah berikut untuk memahaminya:
-
Mula pada kurungan yang paling tertanam.
Mula mencari pangkalan paling luar. Di dalamnya, cari kurungan tertanam. Ulangi proses itu sehingga anda telah melakukan perjalanan ke pasangan kurung yang paling dalam. Mula menilai subprinter menggunakan peraturan berikut. Sebaik sahaja anda memahami ungkapan itu, pop kembali ke tahap seterusnya dan ulangi proses itu.
-
Dalam sepasang kurungan, menilai setiap operasi mengikut urutan keutamaan.
Urutan yang dinilai oleh pengendali ditentukan oleh keutamaan operator yang ditunjukkan dalam jadual. Indirection datang sebelum pendaraban yang datang sebelum penambahan jadi berikut menambah 1 ditambah 2 kali nilai yang ditunjuk oleh * ptr.
int i = 1 + 2 * * ptr;
Precedence | Operator | Maksud |
---|---|---|
1 | () (unary) | Invoke function |
2 | * and -> ( | 2 |
- (unary) | Mengembalikan negatif hujahnya | 3 |
++ (unary) | Kenaikan | 3 |
4 | * (binari) | Pendaraban |
4 | / (binari) | Divisyen |
4 | % (binari) | Modulo |
5 | + (binari) | Addition |
5 | - (binari) | Penolakan |
6 | && (binari) | |
6 | ! ! | Logik ATAU |
7 | =, * =,% =, + =, - = (khusus) | Jenis penyerahhakan |
Menilai operasi terlebih dahulu yang sama dari kiri ke kanan (kecuali tugasan, yang pergi dengan cara lain). | Kebanyakan operator yang mendahului yang sama menilai dari kiri ke kanan. Oleh itu, berikut menambah 1 hingga 2 dan menambah hasilnya kepada 3: | int i = 1 + 2 + 3; |
-
Perintah penilaian sesetengah pengendali tidak penting. Sebagai contoh, tambahan berfungsi sama dari kiri ke kanan seperti yang dilakukan dari kanan ke kiri. Perintah penilaian membuat banyak perbezaan untuk beberapa operasi seperti pembahagian. Bahagian dibahagikan dengan 8 dan 4 dan membahagikan hasilnya dengan 2:
int i = 8/4/2;
Pengecualian utama kepada peraturan ini adalah tugasan, yang dinilai dari kanan ke kiri:
a = b = c;
Ini memberikan c ke b dan hasilnya kepada a.
Menilai subexpressions tanpa urutan tertentu.
Pertimbangkan ungkapan berikut:
int i = f () + g () * h ();
-
Pendaraban mempunyai keutamaan yang lebih tinggi, jadi anda mungkin mengandaikan bahawa fungsi g () dan h () dipanggil sebelum f (), bagaimanapun, ini tidak berlaku. Panggilan fungsi mempunyai keutamaan tertinggi semua, jadi ketiga-tiga fungsi dipanggil sebelum sama ada pendaraban atau penambahan dilakukan. (Hasilnya dikembalikan dari g () dan h () didarab dan kemudian ditambahkan pada hasil yang dikembalikan dari f ().)
Satu-satunya masa yang perintah yang berfungsi dipanggil membuat perbezaan adalah apabila fungsi mempunyai kesan sampingan seperti membuka fail atau mengubah nilai pemboleh ubah global. Anda pastinya tidak akan menulis program anda supaya mereka bergantung kepada jenis kesan sampingan ini.
Lakukan apa-apa jenis penukaran hanya jika perlu.
Anda tidak boleh membuat penukaran jenis lebih daripada yang diperlukan. Sebagai contoh, ungkapan berikut mempunyai sekurang-kurangnya tiga dan mungkin empat jenis penukaran:
float f = 'a' + 1;
-
The char 'a' mesti dipromosikan ke int untuk melakukan tambahan itu. Int kemudian ditukar menjadi dua kali dan kemudian ditukarkan kepada satu terapung ketepatan. Ingat bahawa semua aritmetik dilakukan sama ada dalam int atau berganda. Secara umumnya anda harus mengelak daripada melakukan aritmetik pada jenis watak dan mengelakkan terapi ketepatan tunggal sama sekali.
5 Cara Menghindari Masalah Pointer di C ++
Dalam C ++,
pointer
adalah pembolehubah yang mengandungi alamat objek dalam memori dalaman komputer. Gunakan langkah-langkah ini untuk mengelakkan masalah dengan petunjuk dalam C ++:
Mulakan inisial apabila diisytiharkan. Jangan biarkan pemboleh ubah penunjuk yang tidak diingini - perkara tidak akan menjadi terlalu buruk jika petunjuk tidak dinyalakan selalu mengandungi nilai rawak - majoriti nilai rawak adalah nilai penunjuk haram dan akan menyebabkan program tersebut runtuh sebaik sahaja ia digunakan. Masalahnya ialah bahawa pembolehubah yang tidak diingini cenderung mengambil nilai yang lain, pembolehubah penunjuk sebelumnya yang digunakan. Masalah ini sangat sukar untuk debug. Jika anda tidak tahu apa lagi untuk memulakan penuding, mulailahnya ke nullptr. nullptr dijamin menjadi alamat yang menyalahi undang-undang.
-
Sifar keluar selepas anda menggunakannya.
Begitu juga, sentiasa sifar pembolehubah penunjuk apabila penunjuk tidak lagi sah dengan memberikan nilainya nullptr. Ini terutamanya berlaku apabila anda mengembalikan blok ingatan ke timbunan menggunakan padam; sentiasa sifar penunjuk selepas mengembalikan memori timbunan.
Alihkan memori dari timbunan dan kembalikan ke timbunan pada "tahap" yang sama untuk mengelakkan kebocoran memori.
-
Sentiasa cuba untuk memulangkan blok memori ke timbunan pada tahap abstraksi yang sama seperti yang anda peruntukkan. Ini secara amnya bermakna cuba memadam memori pada tahap panggilan fungsi yang sama.
Tangkap pengecualian untuk memadam ingatan apabila perlu.
-
Jangan lupa bahawa pengecualian boleh berlaku pada hampir bila-bila masa. Jika anda berhasrat untuk menangkap pengecualian dan terus beroperasi (berbanding dengan membiarkan kemalangan program), pastikan anda menangkap pengecualian dan mengembalikan sebarang blok memori ke timbunan sebelum petunjuk yang menunjukkan kepada mereka keluar dari ruang lingkup dan memori itu hilang.
Pastikan jenisnya sepadan dengan tepat.
-
Sentiasa pastikan bahawa jenis petunjuk sesuai dengan jenis yang diperlukan. Jangan mengulangi penunjuk tanpa sebab tertentu. Pertimbangkan yang berikut:
void fn (int * p); void myFunc () {char c = 'a'; char * pC = & c; fn ((int *) pC);}
-
Fungsi di atas dikompil tanpa aduan kerana penunjuk aksara pC telah kembali ke int * untuk menyesuaikan perisytiharan fn (int *); Walau bagaimanapun, program ini hampir pasti tidak berfungsi. Fungsi fn () menjangkakan penunjuk kepada integer 32-bit penuh dan tidak sedikit char 8 bit rinky-dink. Jenis masalah ini amat sukar untuk diselesaikan.
Bagaimana dan Bila Membuat Salinan dalam C ++
Kelas-kelas yang memperuntukkan sumber dalam pembina mereka harus biasanya termasuk pembangun salinan untuk membuat salinan sumber-sumber ini. Mengikut blok memori baru dan menyalin kandungan asal ke dalam blok baru ini dikenali sebagai membuat
salinan mendalam
(berbanding dengan salinan cetek lalai). Gunakan langkah-langkah berikut untuk menentukan bagaimana dan bila untuk membuat salinan dalam C ++:
Sentiasa buat salinan yang mendalam jika pembina memperuntukkan sumber. Secara lalai, C ++ membuat salinan objek yang dipanggil "cetek" oleh ahli-ahli apabila menyampaikannya kepada fungsi atau sebagai hasil tugasan. Anda mesti menggantikan pengendali salinan cetek lalai dengan setara salinannya yang mendalam bagi mana-mana kelas yang memperuntukkan sumber dalam pembina. Sumber yang paling biasa yang diperuntukkan adalah memori timbunan yang dikembalikan oleh pengendali baru. Sentiasa masukkan destructor untuk kelas yang memperuntukkan sumber.
-
Jika anda membuat pembina yang memperuntukkan sumber, anda mesti membuat pemusnah yang memulihkannya. Tiada pengecualian.
Sentiasa mengisytiharkan maya destruktor.
-
Ralat pemula biasa adalah melupakan untuk mengisytiharkan maya destruktor anda. Program ini berjalan lancar sehingga beberapa pengaturcara yang tidak curiga datang dan mewarisi dari kelas anda. Program ini masih berfungsi, tetapi kerana destructor di kelas asas tidak boleh digunakan dengan betul, kebocoran memori dari program anda seperti penapis sehingga ia akhirnya terhempas. Masalah ini sukar dicari.
Sentiasa masukkan pembina salinan untuk kelas yang memperuntukkan sumber.
-
Konstruktor salinan mencipta salinan yang sesuai objek semasa dengan memperuntukkan memori dari timbunan dan menyalin kandungan objek sumber.
Selalu mengatasi pengendali tugasan untuk kelas yang memperuntukkan sumber.
-
Pengaturcara harus digalakkan daripada pengendali yang mengagumkan, tetapi operator tugasan adalah pengecualian. Anda harus mengatasi pengendali tugasan untuk mana-mana kelas yang memperuntukkan sumber dalam pembina.
Pengendali tugasan harus melakukan tiga perkara:
-
Pastikan objek tangan kiri dan kanan bukan objek yang sama. Dengan kata lain, pastikan bahawa pemrogram aplikasi tidak menulis sesuatu seperti (a = a). Jika mereka tidak, jangan berbuat apa-apa.
Minta kod yang sama sebagai destructor di objek kiri untuk mengembalikan sumbernya.
Minta kod yang sama sebagai pembina salinan untuk membuat salinan objek kanan ke objek kiri.
-
Jika anda tidak boleh melakukannya, kemudian hapuskan pembangun salinan dan operator tugasan supaya program tidak boleh membuat salinan objek anda.
-
Jika anda tidak dapat melakukannya kerana pengkompil anda tidak menyokong ciri pembina C ++ 2011, buat pembuat salinan dan pembekal salinan kosong dan mengisytiharkan mereka dilindungi untuk menyimpan kelas lain daripada menggunakannya.
-