Apakah kebiasaan yang baik untuk menggunakan ekspresi C dalam kode C ++?

19

Di sekolah kami mulai belajar C tahun ini, meskipun kenyataannya saya jauh di depan kelas, dan saya belajar Java, C ++ dan C sementara kelas berada di dasar C. Bagaimanapun, saya telah mendokumentasikan diri saya sendiri, membaca buku, artikel, dan saya sudah bertanya kepada guru saya mengapa saya harus belajar C, dan dia mengatakan itu adalah dasar dari C ++. Ketika saya pertama kali memulai pemrograman saya menemukan C ++ banyak lebih mudah, saya kemudian belajar C. Tapi dalam buku Anda dapat melihat bahwa kode C bekerja di C ++ namun tidak berjalan sebaliknya.

Pertanyaan saya cukup mudah ~ Apakah ini kebiasaan yang baik untuk menggunakan ekspresi C di C ++? Biarkan saya memberi Anda sebuah contoh:

Haruskah kode ini

#include <stdio.h>
#include <iostream>

int main() {
int x;
scanf("%d", &x);
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

Lebih efisien atau lebih baik dengan cara apa pun selain ini:

#include <iostream>

int main() {
int x;
cin >> x;
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

Saya telah melakukan beberapa dokumentasi mudah tentang hal ini di beberapa buku tua yang berdebu, dan dari apa yang saya dapat temukan, menggunakan scanf bukan cout juga menyiram aliran atau sesuatu seperti itu, jadi pada dasarnya saya bertanya apakah lebih baik menggunakan scanf dan di konteks apa.

Ini juga berlaku untuk file IO karena saya selalu menemukan FIle IO lebih mudah di C daripada di C ++. Pertanyaan ini berlaku untuk hampir setiap ekspresi umum dalam C yang diterapkan pada C ++. Ini juga penting bahwa saya menggunakan kompiler modern dan bagaimanapun ini seharusnya tidak masalah karena saya bertanya apakah itu kebiasaan pemrograman yang baik untuk menggunakan ekspresi C dalam kode C ++.

Mungkin ada kontra dan pro dalam melakukan ini, tapi saya hanya mencari jenis jawaban ya / mengapa, tidak / mengapa.

Juga jika ada perincian saya tidak mengirim komentar.

Bugster
sumber
12
Berhati-hatilah dengan pencampuran stdiodan iostream. Ada pesanan dan sinkronisasi tertentu yang dijamin dalam keluarga yang tidak perlu diterapkan di luarnya.
David Thornley
Terima kasih atas tipnya, tetapi memo kode itu adalah contoh murni. Bagaimanapun, terima kasih.
Bugster
25
Jika Anda mempelajari pemrograman; Anda harus mempelajari lekukan yang tepat!
bitmask
5
scanf () bukan contoh yang bagus; sangat rentan kesalahan untuk digunakan sehingga saya akan menyarankan Anda untuk menghindarinya di C atau C ++.
Russell Borogove
1
Mungkin hanya kode sampel saja, tetapi komentar David benar-benar menyentuh inti masalah mengapa Anda tidak harus menggunakan idiom C saat pemrograman di C ++. Mereka bahasa yang sama sekali berbeda; jangan membingungkan mereka lebih dari Anda membingungkan Java dan C, atau C ++ dan Visual Basic.
Cody Grey

Jawaban:

36

Tidak, itu kebiasaan buruk. Ketika Anda melakukan ini untuk mencari nafkah, Anda mungkin akan berakhir dengan melanggar panduan gaya yang dipatuhi oleh tim Anda (atau paling tidak mendapat pukulan selama ulasan kode).

Ya itu berfungsi, tetapi jika ada c ++ yang setara, gunakan itu. (mis. cobalah untuk tidak bergaul printfsdengan couts)

jglouie
sumber
+1 - Singkat dan to the point. Dan ini menyoroti poin utama dalam jawaban saya bahwa pedoman tim membantu menyatukan orang dan menyatukan mereka sehingga mereka dapat bekerja sama.
jmort253
Komentar ini cukup banyak menjawab pertanyaan saya dengan benar dan membawa argumen yang kuat. Terima kasih.
Bugster
1
@ Thelan terima kasih. semua orang punya jawaban bagus untuk pertanyaan ini.
jglouie
1
Catatan: menggunakan printfsecara konsisten akan berfungsi sama baiknya dengan menggunakan coutsecara konsisten. Satu-satunya masalah adalah mencampurkan keduanya, dan gaya.
user253751
Bisakah Anda memberikan contoh fitur dalam C yang tidak memiliki setara C ++?
klutt
20

Secara umum, C dan C ++ dipandang seolah-olah mereka adalah dua bahasa yang sepenuhnya terpisah. Oleh karena itu, mungkin dianggap sebagai bentuk yang buruk untuk menggunakan sintaks C dalam program C ++.

Anda benar; Namun, kode C itu akan dikompilasi dengan baik. Itu benar-benar tergantung pada seberapa fleksibel perusahaan Anda dalam hal mengikuti standar. Jika saya pernah ditanya pertanyaan dalam sebuah wawancara, saya pasti akan membiarkan pewawancara tahu bahwa C bekerja di C ++, tetapi juga bahwa C dan C ++ adalah dua bahasa yang terpisah dan mungkin tidak boleh dicampur kecuali ada, sangat, sangat alasan bagus untuk melakukannya.

Hal lain yang perlu dipertimbangkan adalah standar membantu menciptakan platform di mana lebih banyak orang dapat dengan mudah bekerja dengan kode. Meskipun Anda beruntung memiliki guru yang mendorong Anda untuk belajar C, tidak semua orang mungkin seberuntung itu. Oleh karena itu, mencampurkan C dalam program C ++ dapat membingungkan seseorang yang belum pernah belajar C.

Singkatnya, hanya karena Anda dapat melakukan sesuatu tidak berarti Anda harus melakukannya, dan hanya karena Anda seharusnya tidak melakukan sesuatu tidak berarti Anda tidak bisa :)

jmort253
sumber
Saya melihat. Bagaimana dengan fungsionalitas, apakah ada kasus tertentu ketika sintaks C lebih baik daripada sintaks C ++?
Bugster
10

C ++ adalah kompatibel dengan C oleh desain, jadi biasanya kode C akan dikompilasi oleh kompiler C ++ baik-baik saja ( biasanya karena ada kata-kata cadangan tambahan dalam C ++ yang tidak dalam C, dan dapat digunakan dalam kode C melanggar kompilasi).

Namun, saya melihatnya sebagai kode campuran praktik buruk. Jika Anda menggunakan scanf- gunakan printf, jika Anda menggunakan operator >>- gunakan operator <<. Alasannya adalah bahwa operator C ++ yang kelebihan beban mungkin merangkum fungsionalitas yang tidak Anda sadari, dan ketidakcocokan mereka akan menyebabkan program Anda melakukan hal-hal yang tidak Anda inginkan.

Tidak ada alasan khusus untuk memilih sintaks C dalam kode C ++, ini adalah bahasa yang berbeda, dan ketika menggunakan sintaks C dalam kode C ++ - Anda masih menulis kode C ++ , hanya saja tidak menggunakan banyak alat canggihnya.

littleadv
sumber
5
Ketidakcocokan antara C dan C ++ lebih dari sekedar kata kunci. Perubahan sistem pengetikan, dan ada fitur yang ada di C (terutama C99), yang tidak ada di C ++. (Misalnya, array panjang variabel).
Arafangion
9

Jika kita mengesampingkan gaya pengkodean dan masalah estetika, ada juga berbagai masalah teknis yang Anda hadapi saat menggunakan C dalam kode C ++:

  • Apa itu C? C90, C99 atau C11? Mungkin ada berbagai masalah kompatibilitas tergantung pada standar C mana yang Anda gunakan. Jenis Boolean, // komentar, fitur C99 seperti VLA, inisialisasi yang ditunjuk, dll.

  • C ++ memiliki pengetikan yang lebih ketat dari C. Untuk mengkompilasi kode C dalam C ++, Anda kemungkinan besar harus menambahkan berbagai typecast untuk mendapatkan tipe yang diharapkan. Ini berarti bahwa Anda mungkin harus menulis ulang kode C berkualitas baik untuk produksi di C ++.

  • Typecast yang diberlakukan oleh pengetikan yang lebih ketat umumnya hanya hal yang baik, tetapi dalam beberapa kasus mereka dapat memperkenalkan atau menyembunyikan bug. Ambil contoh pemeran yang terkenal dari malloc () sebagai contoh. Ini harus diketik dalam C ++, tetapi tidak pernah dalam C. (1)

  • Menggabungkan fungsionalitas C dan C ++ dapat menyebabkan bug dan perilaku yang tidak terdefinisi. Misalnya, itu tidak akan berfungsi untuk mengalokasikan dengan malloc () dan membebaskan dengan menghapus . (2)

  • Masalah keamanan utas. Perpustakaan standar C tidak aman untuk thread. Pustaka C ++ standar mungkin aman thread atau tidak, jika ya, lalu menambahkan panggilan fungsi Pustaka ke kode Anda akan menghancurkannya.

    Sebagai sidenote untuk pemrogram Windows: kompiler Visual C ++ memiliki bug yang bocor selama beberapa waktu, ketika fungsi Windows API CreateThread () digunakan dalam program yang sama dengan pustaka C. (3, 4)

  • Konvensi panggilan mungkin merupakan masalah pada beberapa kompiler, memaksa satu untuk digunakan extern "C"untuk secara eksplisit memberi tahu fungsi mana yang harus dihubungkan dengan "Konvensi pemanggilan C".

  • Detail yang menjengkelkan. Operator koma berperilaku berbeda. Tanda koma dalam deklarasi struct / enum diizinkan dalam C99 / C11 tetapi tidak dalam C ++. Ruang lingkup berbagai jenis variabel dan fungsi diperlakukan secara berbeda. Dll.

Bahkan ada lebih banyak kasus.


Referensi:

  1. http://c-faq.com/malloc/cast.html
  2. http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.3
  3. http://www.flounder.com/badprogram.htm#CreateThread
  4. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx

sumber
7

Alasan mengapa C ++ dapat mengkompilasi C hanya untuk "kompatibilitas mundur" (hindari untuk menulis ulang kode kerja yang ada).

Tetapi C ++ memiliki filosofi yang berbeda sehubungan dengan c. Menggabungkan mereka tidak memberikan layanan yang baik untuk mereka berdua.

Cara C dan C ++ mengelola i / o dapat mengandalkan cara berbeda untuk mengelola kondisi internal i / o. Jadi - paling tidak - gunakan input dan output secara konsisten.

Dan dalam program C ++, hormati gaya C ++ (kecuali secara khusus diminta untuk melakukannya di tempat lain)

Emilio Garavaglia
sumber
5

Saya akan mengatakan bahwa belajar C pertama adalah, IMHO, ide yang bagus. Dengan cara ini orang mulai memahami perangkat keras yang mereka gunakan untuk menulis perangkat lunak.

Menggabungkan kedua bahasa ini bukanlah ide yang baik. Karena Anda mendapatkan kompleksitas gila dari C ++ ditambah dengan twiddling bit mentah yang umum untuk C.

Seperti yang Anda lihat, bahkan dalam contoh sederhana seperti milik Anda, ada masalah sinkronisasi dengan berbagai jenis aliran, dan penyangga internal. Tetapi juga, pendekatan C&C ++ tidak lebih fleksibel dengan cara apa pun. Beralihlah ke kelas x, dan tidak ada operator yang menggunakan streaming dan lainnya.

Ini rumit...

Saya benar-benar berpikir bahwa programmer C ++ yang baik harus tahu bagaimana bit dibalik setiap konstruk, dan apa perilaku tersembunyi.

Tetapi mempelajari C ++, setidaknya lebih dari 50% darinya, membutuhkan 5+ tahun pengkodean profesional, dan Anda tidak bisa mengelolanya dalam kurikulum yang panjangnya 6 bulan dengan 20 jam pengalaman kerja.

Jika saya akan menggunakan konstruksi C ++ di C, saya tidak akan menggunakan stream, mereka adalah cara sederhana dari pandangan mata burung, dan membuat orang percaya bahwa pengembangan perangkat lunak itu mudah, tetapi menyembunyikan kerumitan ekstra tanpa banyak manfaat dalam banyak situasi.

Kelas wrapper RAII, templat, kelebihan beban, kebenaran konst, dan kelas abstrak murni untuk antarmuka umum (jangan gunakan f-ng Java seperti di sini PLEASE!) Adalah kandidat yang baik. Karena mereka menambah keamanan, generalisasi dan kemudahan penggunaan yang sangat penting untuk proyek kehidupan nyata. Pastikan untuk mengingat tentang hal-hal seperti penghancuran virtual, sifat eksplosif dari konstruksi penyalinan standar, overhead runtime, kebenaran const dll di sini juga.

Coder
sumber