Prinsip apa yang dipelajari dari C yang tidak dapat dipelajari dalam bahasa tingkat yang lebih tinggi? [Tutup]
11
Saya percaya C adalah bahasa yang baik untuk mempelajari prinsip-prinsip di balik pemrograman. Apa yang ingin Anda pelajari dalam bahasa tingkat rendah yang "disihir" jauh dari bahasa tingkat tinggi, seperti Ruby?
Anda belajar sihir, atau sebagian darinya. Karena C "lebih dekat ke logam," Anda belajar lebih banyak tentang logam.
Robert Harvey
1
Saya tidak pernah sepenuhnya memahami konsep referensi sampai saya menemukan C ++.
user6245072
6
C akan mengajari Anda apa sebenarnya stack overflow. Cara yang sulit.
david25272
1
Saya berharap programmer baru akan mulai dengan mempelajari pemrograman Pascal dan terstruktur yang baik. Anda belajar mengekspresikan diri secara logis dan terstruktur.
Bent
2
Sesuatu yang hanya diajarkan oleh C dan C ++ adalah kompiler adalah musuh terburuk Anda.
CodesInChaos
Jawaban:
9
Tidak ada prinsip, dalam pengertian abstrak umum ilmu komputer, yang hadir dalam C yang tidak juga hadir dalam bahasa tingkat yang lebih tinggi. Semua ilmu komputer bermuara pada algoritma, dan semua algoritma dapat diimplementasikan dalam bahasa apa pun yang Turing-lengkap seperti C.
Perbedaan yang dibawa C dari bahasa tingkat tinggi mirip dengan perbedaan yang dibawa kode mesin selain C: Hubungan mesin dengan kode.
Saat Anda menulis kode dalam bahasa tingkat tinggi, Anda (umumnya) tidak peduli dengan bagaimana kode Anda berinteraksi dengan mesin. Mesin virtual yang didefinisikan oleh bahasa itu sendiri menyembunyikan banyak aspek dari eksekusi kode.
Di C, interaksi program Anda dengan memori disimpan di garis depan. Ini lebih dari sekedar bahwa Anda harus mengelola penggunaan heap, itu termasuk interaksi kode Anda dengan stack, dan bagaimana akses kode memori belaka Anda mempengaruhi perilaku dan kinerja kode Anda - bahkan urutan urutan memori yang diakses dapat dibiarkan luput dari perhatian Anda, karena membaca memori yang salah pada waktu yang salah dapat secara efektif melumpuhkan kinerja.
Dalam bahasa tingkat tinggi, hal-hal ini tidak begitu jelas. Memori dialokasikan dan dialokasikan tanpa sepengetahuan Anda, dan kadang-kadang tanpa dorongan Anda. Paling sering, ini hanya di luar kendali Anda. Kapan, di mana, bagaimana, dan mengapa sebagian besar alokasi memori disembunyikan dari Anda.
Demikian juga, di arah lain, menulis kode mesin atau kode perakitan membawa lebih banyak detail ke latar depan: Hampir tidak ada yang tersisa di luar ruang lingkup Anda, dan kode Anda harus ditulis dengan sadar setiap alokasi, setiap sumber daya, setiap bagian dari data yang melewati melalui register CPU - pengetahuan yang sejauh ini dihapus dari bahasa tingkat tinggi menjadi misterius.
Saya tidak pernah mengerti mengapa orang selalu menyebut Turing-kelengkapan dalam diskusi semacam ini. Kelengkapan Turing tidak bermakna dalam konteks ini; C tidak berbeda dari bahasa pemrograman lain dalam hal itu, jadi tidak ada yang bisa dipelajari tentang kelengkapan Turing dengan beralih ke C. Satu-satunya waktu kelengkapan Turing menjadi relevan adalah ketika membahas sesuatu yang tidak Turing-lengkap, seperti CSS atau HTML . Sial, jika Anda menyipit cukup keras, bahkan itu adalah Turing-lengkap . Pertanyaan yang lebih bermakna berfokus pada kegunaan.
Robert Harvey
3
@RobertHarvey Maksud saya adalah selama bahasa memiliki kemampuan komputasi minimum yang masuk akal, "level" -nya menjadi tidak relevan dari sudut pandang algoritma, yang merupakan satu-satunya hal yang penting dalam konteks ini.
greyfade
3
Karena Anda membuat poin yang sama sekali tidak penting untuk pertanyaan OP. Pemrogram melakukan ini sepanjang waktu; mereka melontarkan ungkapan "Turing-complete" seperti itu sebenarnya memiliki beberapa penggunaan yang bermakna dalam istilah praktis. Tidak, kecuali untuk menunjukkan bahwa itu tidak masalah.
Robert Harvey
2
<irony> Biologi hanyalah kasus khusus kimia, yang merupakan kasus khusus fisika partikel. Tidak ada yang bisa Anda pelajari dari biologi jika Anda tahu fisika partikel. Benar? </irony>
Florian F
3
Layak menunjukkan bahwa C hanya mengharuskan Anda untuk membuat alokasi dan deallokasi eksplisit, tetapi mereka masih menyangkut mesin abstrak, sama seperti dalam bahasa "tingkat yang lebih tinggi" - mesin fisik (misalnya) x86 masih berada di luar lingkup C. One dapat membuat VM dengan kotak pasir sempurna yang menginterpretasikan kode C tetapi tidak memiliki kendali atas alokasi memori mesin fisik dan masih bisa menjadi implementasi yang 100% sesuai.
Theodoros Chatzigiannakis
13
Saya tahu C adalah bahasa yang baik untuk mempelajari prinsip-prinsip di balik pemrograman.
Saya tidak setuju. C tidak memiliki terlalu banyak fitur untuk mempelajari prinsip-prinsip di balik pemrograman. Fitur C untuk membuat abstraksi itu mengerikan, dan abstraksi adalah salah satu prinsip utama di balik pemrograman.
Jika Anda ingin mempelajari cara kerja perangkat keras, dan karenanya memiliki simpati mekanis untuk mesin, Anda harus mempelajari kode mesin, alias arsitektur kumpulan instruksi, dan juga mempelajari konstruksi cache dari CPU modern. Perhatikan bahwa saya tidak merekomendasikan bahasa rakitan, cukup pahami instruksi perangkat keras, sehingga Anda mengerti apa yang dihasilkan oleh kompiler.
Jika Anda ingin mempelajari prinsip-prinsip pemrograman, gunakan bahasa modern seperti Java, C #, atau Swift, atau salah satu dari banyak lainnya seperti Rust. Juga, pelajari berbagai jenis paradigma pemrograman, termasuk fungsional.
C baik-baik saja dalam membuat abstraksi. Anda dapat menulis metode dalam C, dan Anda dapat mengemas data sebagai struktur dalam C. Seluruh sistem operasi telah dibangun menggunakan C. Apa yang C tidak pandai adalah memuaskan semua ide "modern" semua orang tentang apa yang harus dilihat oleh orientasi objek. Suka.
Robert Harvey
4
Tidak terlalu. Level C sedikit lebih tinggi dari ASM. Hanya saja, jangan berharap untuk menggunakan kelas di dalamnya, meskipun ada cara untuk melakukannya , jika Anda cenderung.
Robert Harvey
4
Ganti "Brainfuck" untuk "assembler" di komentar Anda, dan itu harus tetap berlaku. Tapi itu tidak berarti saya akan menggunakan Brainfuck dalam waktu dekat.
Robert Harvey
6
Argumen Anda tentang fitur C benar-benar hanya pantas jika Anda percaya kelas (dan pengumpulan sampah, dll.) Adalah elemen yang diperlukan untuk mengajar programmer baru (yang saya tidak punya). Tidak ada seorang pun di sini yang menganjurkan untuk menggunakan kelas dalam bahasa tanpa kelas.
Robert Harvey
5
@ Robert, argumen saya adalah bahwa C adalah bahasa tingkat rendah, dan karena itu bukan bahasa terbaik untuk memahami prinsip-prinsip pemrograman, yang juga dapat kita katakan tentang assembler, dan, hanya karena mereka adalah bahasa tingkat yang lebih rendah tidak berarti mereka entah bagaimana lebih dekat dengan prinsip pemrograman "benar". Bahasa-bahasa ini lebih baik daripada memahami bagaimana perangkat keras dan sistem operasi bekerja, dan jika itu yang menarik, saya merekomendasikan untuk melompat ke tingkat terendah, dalam pembelajaran mengatur arsitektur dan bahasa mesin. Kalau tidak, ada banyak bahasa untuk dipilih.
C bukan pengecualian dari aturan di atas. Ini dijelaskan dalam istilah mesin abstrak yang tidak memiliki gagasan tentang perangkat keras Anda yang sebenarnya.
Dengan demikian, ketika orang mengatakan bahwa C mengajarkan Anda bagaimana komputer Anda benar-benar bekerja, yang biasanya mereka maksud adalah bahwa C mengajarkan Anda bagaimana C bekerja. Tapi C begitu meresap dalam pemrograman sistem, bisa dimengerti bahwa banyak orang mulai bingung dengan komputer itu sendiri. Dan saya pribadi akan mengatakan bahwa mengetahui bagaimana C bekerja seringkali lebih penting daripada mengetahui bagaimana komputer itu sendiri bekerja.
Tapi tetap saja, C dan komputer adalah hal yang berbeda. Perangkat keras yang sebenarnya sebenarnya rumit - dengan cara yang membuat spec C membaca seperti buku anak-anak. Jika Anda tertarik dengan cara kerja perangkat keras Anda, Anda selalu dapat mencari manual dan mulai menulis kode dalam assembler. Atau Anda selalu dapat mulai belajar tentang sirkuit digital sehingga Anda dapat merancang beberapa perangkat keras sendiri. (Paling tidak, Anda akan menghargai seberapa tinggi level C itu.)
Bagaimana cara Anda belajar? Dan bagaimana Anda belajar?
Oke, sebenarnya belajar tentang perangkat keras melibatkan hal-hal selain C. Tapi bisakah C mengajarkan hal lain kepada programmer hari ini?
Saya pikir itu tergantung.
Ada beberapa yang akan mengatakan bahwa Anda dapat mempelajari konsep dengan lebih baik dengan bekerja di lingkungan yang menawarkan dan mendorongnya, sering kali dalam berbagai cara.
Ada beberapa yang akan mengatakan bahwa Anda dapat mempelajari konsep dengan lebih baik dengan bekerja di lingkungan yang tidak menawarkannya dan di mana Anda harus membangunnya sendiri.
Jangan terlalu cepat memilih salah satu dari kemungkinan ini. Saya telah menulis kode selama bertahun-tahun dan saya masih tidak tahu yang mana jawaban yang benar, atau apakah jawaban yang benar hanya satu dari dua, atau apakah ada jawaban yang benar mengenai masalah ini.
Saya sedikit cenderung percaya bahwa Anda mungkin pada akhirnya harus menerapkan kedua opsi, secara longgar dalam urutan yang saya jelaskan. Tapi saya tidak berpikir ini benar-benar masalah teknis, saya pikir ini sebagian besar bersifat pendidikan. Setiap orang tampaknya belajar dengan cara yang sangat berbeda.
Eksklusif dalam C
Jika Anda menjawab pertanyaan di atas dengan setidaknya melibatkan opsi kedua yang saya usulkan, maka Anda sudah memiliki beberapa jawaban: apa pun yang dapat dipelajari dalam bahasa tingkat yang lebih tinggi dapat dipelajari dengan lebih baik dengan menciptakannya kembali di C atau di paling tidak diperluas dengan menambahkan C ke dalam campuran.
Tetapi, terlepas dari jawaban Anda, tentu ada beberapa hal yang dapat Anda pelajari hampir secara eksklusif dari C (dan mungkin beberapa bahasa lain).
C secara historis penting. Ini adalah tonggak sejarah yang dapat Anda lihat dan hargai dari mana kami berasal dan mungkin mendapatkan lebih banyak konteks tentang ke mana kita akan pergi. Anda dapat menghargai mengapa batasan tertentu ada dan Anda dapat menghargai bahwa batasan tertentu telah dicabut.
C dapat mengajarkan Anda untuk bekerja di lingkungan yang tidak aman. Dengan kata lain, itu bisa melatih Anda untuk mengawasi ketika bahasa (bahasa apa pun) tidak bisa atau tidak mau melakukannya untuk Anda, dengan alasan apa pun. Ini dapat membuat Anda menjadi programmer yang lebih baik bahkan di lingkungan yang aman karena Anda akan menghasilkan lebih sedikit bug sendiri dan karena Anda akan dapat mematikan keselamatan sementara untuk memeras beberapa kecepatan ekstra dari program Anda yang dinyatakan aman (misalnya penggunaan pointer). dalam C #), dalam kasus-kasus di mana keselamatan datang dengan biaya runtime.
C dapat mengajarkan Anda bahwa setiap objek memiliki persyaratan penyimpanan, tata letak memori, fakta bahwa memori dapat diakses melalui ruang alamat yang terbatas, dan sebagainya. Sementara bahasa lain tidak membutuhkan perhatian Anda pada masalah ini, ada beberapa kasus di mana beberapa intuisi yang diperoleh dapat membantu Anda membuat keputusan yang lebih tepat.
C dapat mengajarkan Anda tentang perincian tautan dan file objek serta seluk-beluk lainnya melalui sistem build-nya. Ini dapat memberi Anda pemahaman langsung tentang bagaimana program yang disusun secara asli sering kali berubah dari kode sumber ke eksekusi.
C dapat membengkokkan pikiran Anda untuk berpikir dengan cara-cara baru melalui konsep perilaku yang tidak terdefinisi. Perilaku tidak terdefinisi adalah salah satu konsep favorit saya dalam pengembangan perangkat lunak, karena studi tentang implikasinya pada kompiler non-klasik adalah latihan mental yang unik yang tidak bisa Anda dapatkan dari bahasa lain. Namun, Anda harus menolak coba-coba dan mulai mempelajari bahasa dengan cara yang cermat dan hati-hati sebelum Anda dapat sepenuhnya menghargai aspek ini.
Tetapi mungkin realisasi paling penting yang dapat diberikan C kepada Anda, sebagai bahasa yang kecil, adalah gagasan bahwa semua pemrograman bermuara pada data dan operasi . Anda mungkin ingin melihat hal-hal sebagai kelas modular dengan hierarki dan antarmuka dengan pengiriman virtual, atau nilai-nilai abadi yang elegan yang dioperasikan menggunakan fungsi matematika murni. Dan itu tidak masalah - tetapi C akan mengingatkan Anda bahwa itu semua hanya operasi data + . Ini adalah pola pikir yang berguna karena memungkinkan Anda untuk menurunkan beberapa hambatan mental.
Alasan mengapa C baik untuk belajar bukanlah karena ia mengajarkan prinsip apa pun . Ini mengajarkan Anda, bagaimana segala sesuatu bekerja .
C dapat dibandingkan dengan salah satu mobil tua yang bagus dari tahun 70an atau 80an, yang baru saja dibuat untuk dikendarai. Anda dapat memisahkannya, sekrup demi sekrup, dan memahami bagaimana masing-masing bagian bekerja, dan bagaimana ia bekerja bersama dengan bagian lain yang dapat Anda ambil di tangan Anda untuk melihatnya. Setelah Anda memahami semua bagian, Anda memiliki gambaran yang sangat jelas bagaimana keseluruhan beroperasi.
Bahasa modern lebih seperti mobil modern di mana mesinnya pada dasarnya adalah kotak hitam, terlalu rumit untuk dipahami oleh pemilik mobil biasa. Mobil-mobil itu dapat melakukan banyak hal, heck, pada hari-hari ini secara aktif belajar mengemudi sendiri. Dan dengan kerumitan dan kenyamanan itu, antarmuka pengguna telah dipindahkan jauh dari apa yang sebenarnya terjadi di mesin.
Ketika Anda belajar pemrograman dalam C, Anda bersentuhan dengan banyak sekrup dan mur yang terbuat dari komputer. Ini memungkinkan Anda untuk mengembangkan pemahaman tentang mesin itu sendiri. Sebagai contoh, ini memungkinkan Anda untuk memahami mengapa itu bukan ide yang baik untuk membangun string panjang seperti ini:
java.lang.String result ="";for(int i =0; i < components.size; i++){
result = result + components[i];};
(Saya harap, ini adalah Java yang benar, saya belum menggunakannya dalam beberapa saat ...) Dari contoh kode ini, tidak jelas mengapa loop memiliki kompleksitas kuadratik. Tapi itulah masalahnya, dan itu adalah alasan mengapa kode ini akan berhenti bekerja ketika Anda memiliki beberapa juta komponen kecil untuk digabungkan. Pemrogram C yang berpengalaman tahu langsung di mana masalahnya, dan kemungkinan akan menghindari menulis kode seperti itu di tempat pertama.
Aku sangat setuju. C akan mengajarkan Anda banyak hal tentang bagaimana hal-hal bekerja, yang berjalan jauh menuju pemahaman a) mengapa bahasa tingkat tinggi ditulis (misalnya, apa yang mereka maksudkan dengan abstrak), dan b) bagaimana bahasa tingkat tinggi itu bekerja di belakang layar, yang pasti memiliki pengetahuan yang baik. Ini tidak akan mengajarkan prinsip-prinsip dan mungkin tidak semudah itu, tetapi Anda akan menghormatinya, komputer, dan pemahaman yang lebih mendalam tentang bahasa tingkat yang lebih tinggi. Baca juga Kembali ke Dasar oleh Joel Spolsky: joelonsoftware.com/articles/fog0000000319.html
jleach
1
Jawaban Anda pasti baik-baik saja, tetapi jika Anda menulis for(int i = 0; i < strlen(s); i++)dalam C, loop juga akan memiliki kompleksitas kuadratik, dan sama tidak jelasnya seperti pada contoh Java Anda ;-)
Doc Brown
Tidak yakin, tapi saya akan percaya kompiler Java untuk mengoptimalkan ini :-)
Bruno Schäpper
Pemrogram Java yang berpengalaman juga tahu langsung di mana masalahnya, dan mungkin akan menghindari penulisan kode seperti itu di tempat pertama. Masalah khusus ini dibahas dalam tutorial Java dasar. Jadi ini jelas bukan sesuatu yang bisa dipelajari dari C tetapi bukan dari Jawa.
Peter Taylor
@PeterTaylor Jika Anda memiliki instruktur Java yang mengetahui C mereka, ya. Tetapi saya ragu bahwa pengetahuan semacam ini akan tetap ada begitu orang yang tahu C sudah mati. Untuk programmer C, itu adalah definisi dari apa C-string, yang memberi tahu mereka bahwa contoh kode saya tidak bisa efisien. Untuk programmer Java, ini adalah pengetahuan yang mendalam, misterius, dan sedikit digunakan tentang abstraksi yang mereka gunakan, yang memberitahu mereka untuk menghindari kode semacam ini. Ok, saya sedikit melebih-lebihkan di sini, tetapi Anda mendapatkan ide: Pemrogram C harus mengetahuinya, pemrogram Java mungkin lolos dengan tidak mengetahuinya.
cmaster - mengembalikan monica
2
Ada bahasa yang lebih baik daripada C untuk mempelajari "prinsip-prinsip di balik pemrograman", terutama prinsip-prinsip teoretis, tetapi C mungkin baik untuk mempelajari beberapa hal praktis dan penting tentang kerajinan tangan. Jawaban greyfade adalah benar benar, tetapi IMHO ada lebih banyak yang dapat Anda pelajari dari C daripada bagaimana mengelola memori sendiri. Sebagai contoh,
cara membuat program dengan penanganan kesalahan lengkap tanpa adanya pengecualian
cara membuat struktur dalam program tanpa dukungan bahasa untuk orientasi objek
bagaimana menangani data tanpa adanya struktur data seperti daftar dinamis yang cukup besar, kamus atau abstraksi string yang berguna
bagaimana menghindari kesalahan umum seperti limpahan array bahkan ketika lingkungan kompiler atau run time tidak memperingatkan Anda secara otomatis
cara membuat solusi generik tanpa dukungan bahasa untuk templat atau generik
dan apakah saya menyebutkan Anda bisa belajar mengelola memori sendiri, tentu saja? ;-)
Selain itu, dengan mempelajari C, Anda akan belajar dari mana persamaan sintaksis C ++, Java, C #, Objective C berasal.
Pada tahun 2005, Joel Spolsky menulis rekomendasi untuk belajar C sebelum bahasa tingkat tinggi lainnya. Argumennya adalah
"Anda tidak akan pernah bisa membuat kode efisien dalam bahasa tingkat yang lebih tinggi."
"Anda tidak akan pernah bisa bekerja pada kompiler dan sistem operasi, yang merupakan beberapa pekerjaan pemrograman terbaik di sekitar."
"Kamu tidak akan pernah dipercaya untuk membuat arsitektur untuk proyek skala besar"
"Jika Anda tidak dapat menjelaskan mengapa while(*s++ = *t++);menyalin string, atau jika itu bukan hal yang paling alami di dunia untuk Anda, yah, Anda pemrograman berdasarkan takhayul
Tentu saja, apa yang ditulisnya pasti dapat diperdebatkan, tetapi banyak argumennya yang masih berlaku hingga saat ini.
C adalah bahasa yang sangat baik untuk dipelajari sebelum Anda mempelajari "hal-hal tingkat tinggi yang menurut Anda tidak didukung C", karena itu membantu Anda memahami bagaimana hal-hal itu benar-benar bekerja (dan seberapa mahal mereka).
Brendan
@ Brendan: Saya tidak yakin apakah maksud dari komentar Anda adalah untuk menyatakan persetujuan, ketidaksepakatan, atau hanya sidenote jawaban saya.
Doc Brown
Program C yang ditulis oleh para profesional dirilis dengan buffer overruns dan hard crash. Jadi, sementara seorang programmer yang disiplin dapat memilih untuk mempelajari hal-hal ini , bahasa C tidak secara inheren mengajar hanya dengan menjadi miskin. Ada banyak cara buruk (dan lebih buruk lagi, mencampurkan beberapa cara tidak konsisten) untuk melakukan penanganan kesalahan tanpa pengecualian dan membuat struktur tanpa objek, misalnya.
Erik Eidt
@ErikEidt: memang, tetapi terutama di ekosfer C ada banyak buku, tutorial, dan materi lain yang akan membahas topik-topik ini. Misalnya, "Menulis Kode Padat" oleh Steve Maguire. Tentu saja, jika seseorang hanya memilih K&R edisi pertama untuk mempelajari sintaksis bahasa, ia mungkin tidak akan menjadi programmer yang lebih baik.
Doc Brown
1
Dua abstraksi dasar komputasi adalah mesin Turing dan kalkulus Lambda, dan C adalah cara untuk bereksperimen dengan pandangan komputasi mesin Turing: kebanyakan suksesi tindakan tingkat rendah yang darinya muncul hasil yang diinginkan. Tetapi Anda harus ingat bahwa C hadir dengan model komputasinya sendiri. Jadi, belajar C akan mengajari Anda perincian tingkat rendah dari mesin abstrak C, yang semakin berbeda dari arsitektur sebenarnya. Salah satu hal pertama yang saya diajarkan di C adalah untuk tidak pernah mencoba mengakali kompiler dengan menerapkan trik "pintar", dan tampaknya kecenderungannya adalah semakin banyak optimisasi dalam kompiler. Seperti dalam bahasa tingkat tinggi lainnya, ketika Anda menulis dalam C, kompiler memahami apa yang Anda harapkan dilakukan pada mesin C abstrak dan mewujudkannya pada perangkat keras yang sebenarnya,
Jadi yang saya maksud adalah bahwa belajar C tidak selalu akan memberi Anda gambaran yang baik tentang apa yang sebenarnya terjadi pada perangkat keras. "C dekat dengan mesin" harus dipahami sebagai "lebih dekat daripada kebanyakan bahasa tingkat tinggi". Mempelajari arsitektur perangkat lunak secara langsung akan lebih bermanfaat jika Anda menginginkan gambaran yang lebih akurat tentang "cara kerjanya".
Di sisi lain, belajar C dapat membiasakan Anda dengan pemrograman sistem, tipe tingkat rendah, pointer dan alokasi memori tertentu. Sedangkan untuk mempelajari algoritma dan struktur data, saya tidak memiliki keuntungan untuk mempelajarinya dalam bahasa C daripada bahasa lain.
Jadi, apa yang bisa diajarkan C kepada Anda bahwa bahasa tingkat yang lebih tinggi tidak bisa?
Philip Kendall
2
Saya pikir jawaban tersirat adalah: " Tidak ada , setidaknya bukan hal-hal yang biasanya diklaim oleh para pendukung". Begitulah cara saya memahami jawabannya.
Jörg W Mittag
-3
Ini adalah pertanyaan yang berakhir sangat terbuka, mungkin tidak memberikan jawaban konklusif. Anda dapat mempelajari hampir semua hal dalam setiap bahasa asalkan Anda memahami internal kerangka kerja bahasa. C memaksa Anda untuk memahami detail yang lebih rendah karena itu terutama dirancang untuk menulis sistem operasi. Bahkan setelah bertahun-tahun, itu masih menjadi salah satu bahasa yang paling banyak digunakan terutama berkat sistem tertanam dan proyek sumber terbuka. Jadi, pertanyaannya adalah apa yang ingin Anda pelajari? Dan di domain mana?
Jawaban:
Tidak ada prinsip, dalam pengertian abstrak umum ilmu komputer, yang hadir dalam C yang tidak juga hadir dalam bahasa tingkat yang lebih tinggi. Semua ilmu komputer bermuara pada algoritma, dan semua algoritma dapat diimplementasikan dalam bahasa apa pun yang Turing-lengkap seperti C.
Perbedaan yang dibawa C dari bahasa tingkat tinggi mirip dengan perbedaan yang dibawa kode mesin selain C: Hubungan mesin dengan kode.
Saat Anda menulis kode dalam bahasa tingkat tinggi, Anda (umumnya) tidak peduli dengan bagaimana kode Anda berinteraksi dengan mesin. Mesin virtual yang didefinisikan oleh bahasa itu sendiri menyembunyikan banyak aspek dari eksekusi kode.
Di C, interaksi program Anda dengan memori disimpan di garis depan. Ini lebih dari sekedar bahwa Anda harus mengelola penggunaan heap, itu termasuk interaksi kode Anda dengan stack, dan bagaimana akses kode memori belaka Anda mempengaruhi perilaku dan kinerja kode Anda - bahkan urutan urutan memori yang diakses dapat dibiarkan luput dari perhatian Anda, karena membaca memori yang salah pada waktu yang salah dapat secara efektif melumpuhkan kinerja.
Dalam bahasa tingkat tinggi, hal-hal ini tidak begitu jelas. Memori dialokasikan dan dialokasikan tanpa sepengetahuan Anda, dan kadang-kadang tanpa dorongan Anda. Paling sering, ini hanya di luar kendali Anda. Kapan, di mana, bagaimana, dan mengapa sebagian besar alokasi memori disembunyikan dari Anda.
Demikian juga, di arah lain, menulis kode mesin atau kode perakitan membawa lebih banyak detail ke latar depan: Hampir tidak ada yang tersisa di luar ruang lingkup Anda, dan kode Anda harus ditulis dengan sadar setiap alokasi, setiap sumber daya, setiap bagian dari data yang melewati melalui register CPU - pengetahuan yang sejauh ini dihapus dari bahasa tingkat tinggi menjadi misterius.
sumber
Saya tidak setuju. C tidak memiliki terlalu banyak fitur untuk mempelajari prinsip-prinsip di balik pemrograman. Fitur C untuk membuat abstraksi itu mengerikan, dan abstraksi adalah salah satu prinsip utama di balik pemrograman.
Jika Anda ingin mempelajari cara kerja perangkat keras, dan karenanya memiliki simpati mekanis untuk mesin, Anda harus mempelajari kode mesin, alias arsitektur kumpulan instruksi, dan juga mempelajari konstruksi cache dari CPU modern. Perhatikan bahwa saya tidak merekomendasikan bahasa rakitan, cukup pahami instruksi perangkat keras, sehingga Anda mengerti apa yang dihasilkan oleh kompiler.
Jika Anda ingin mempelajari prinsip-prinsip pemrograman, gunakan bahasa modern seperti Java, C #, atau Swift, atau salah satu dari banyak lainnya seperti Rust. Juga, pelajari berbagai jenis paradigma pemrograman, termasuk fungsional.
sumber
C dan Mesin (Abstrak)
Sebagian besar bahasa pemrograman dijelaskan dalam istilah mesin abstrak. Kemudian, mereka diimplementasikan menggunakan set alat seperti kompiler, tautan, assembler, interpreter, penganalisa statis, bahasa perantara, dan perangkat keras yang secara kolektif akan menghasilkan hasil yang menghormati setidaknya semua perilaku yang diharapkan dari mesin abstrak, seperti yang diamati oleh sebuah program .
C bukan pengecualian dari aturan di atas. Ini dijelaskan dalam istilah mesin abstrak yang tidak memiliki gagasan tentang perangkat keras Anda yang sebenarnya.
Dengan demikian, ketika orang mengatakan bahwa C mengajarkan Anda bagaimana komputer Anda benar-benar bekerja, yang biasanya mereka maksud adalah bahwa C mengajarkan Anda bagaimana C bekerja. Tapi C begitu meresap dalam pemrograman sistem, bisa dimengerti bahwa banyak orang mulai bingung dengan komputer itu sendiri. Dan saya pribadi akan mengatakan bahwa mengetahui bagaimana C bekerja seringkali lebih penting daripada mengetahui bagaimana komputer itu sendiri bekerja.
Tapi tetap saja, C dan komputer adalah hal yang berbeda. Perangkat keras yang sebenarnya sebenarnya rumit - dengan cara yang membuat spec C membaca seperti buku anak-anak. Jika Anda tertarik dengan cara kerja perangkat keras Anda, Anda selalu dapat mencari manual dan mulai menulis kode dalam assembler. Atau Anda selalu dapat mulai belajar tentang sirkuit digital sehingga Anda dapat merancang beberapa perangkat keras sendiri. (Paling tidak, Anda akan menghargai seberapa tinggi level C itu.)
Bagaimana cara Anda belajar? Dan bagaimana Anda belajar?
Oke, sebenarnya belajar tentang perangkat keras melibatkan hal-hal selain C. Tapi bisakah C mengajarkan hal lain kepada programmer hari ini?
Saya pikir itu tergantung.
Jangan terlalu cepat memilih salah satu dari kemungkinan ini. Saya telah menulis kode selama bertahun-tahun dan saya masih tidak tahu yang mana jawaban yang benar, atau apakah jawaban yang benar hanya satu dari dua, atau apakah ada jawaban yang benar mengenai masalah ini.
Saya sedikit cenderung percaya bahwa Anda mungkin pada akhirnya harus menerapkan kedua opsi, secara longgar dalam urutan yang saya jelaskan. Tapi saya tidak berpikir ini benar-benar masalah teknis, saya pikir ini sebagian besar bersifat pendidikan. Setiap orang tampaknya belajar dengan cara yang sangat berbeda.
Eksklusif dalam C
Jika Anda menjawab pertanyaan di atas dengan setidaknya melibatkan opsi kedua yang saya usulkan, maka Anda sudah memiliki beberapa jawaban: apa pun yang dapat dipelajari dalam bahasa tingkat yang lebih tinggi dapat dipelajari dengan lebih baik dengan menciptakannya kembali di C atau di paling tidak diperluas dengan menambahkan C ke dalam campuran.
Tetapi, terlepas dari jawaban Anda, tentu ada beberapa hal yang dapat Anda pelajari hampir secara eksklusif dari C (dan mungkin beberapa bahasa lain).
C secara historis penting. Ini adalah tonggak sejarah yang dapat Anda lihat dan hargai dari mana kami berasal dan mungkin mendapatkan lebih banyak konteks tentang ke mana kita akan pergi. Anda dapat menghargai mengapa batasan tertentu ada dan Anda dapat menghargai bahwa batasan tertentu telah dicabut.
C dapat mengajarkan Anda untuk bekerja di lingkungan yang tidak aman. Dengan kata lain, itu bisa melatih Anda untuk mengawasi ketika bahasa (bahasa apa pun) tidak bisa atau tidak mau melakukannya untuk Anda, dengan alasan apa pun. Ini dapat membuat Anda menjadi programmer yang lebih baik bahkan di lingkungan yang aman karena Anda akan menghasilkan lebih sedikit bug sendiri dan karena Anda akan dapat mematikan keselamatan sementara untuk memeras beberapa kecepatan ekstra dari program Anda yang dinyatakan aman (misalnya penggunaan pointer). dalam C #), dalam kasus-kasus di mana keselamatan datang dengan biaya runtime.
C dapat mengajarkan Anda bahwa setiap objek memiliki persyaratan penyimpanan, tata letak memori, fakta bahwa memori dapat diakses melalui ruang alamat yang terbatas, dan sebagainya. Sementara bahasa lain tidak membutuhkan perhatian Anda pada masalah ini, ada beberapa kasus di mana beberapa intuisi yang diperoleh dapat membantu Anda membuat keputusan yang lebih tepat.
C dapat mengajarkan Anda tentang perincian tautan dan file objek serta seluk-beluk lainnya melalui sistem build-nya. Ini dapat memberi Anda pemahaman langsung tentang bagaimana program yang disusun secara asli sering kali berubah dari kode sumber ke eksekusi.
C dapat membengkokkan pikiran Anda untuk berpikir dengan cara-cara baru melalui konsep perilaku yang tidak terdefinisi. Perilaku tidak terdefinisi adalah salah satu konsep favorit saya dalam pengembangan perangkat lunak, karena studi tentang implikasinya pada kompiler non-klasik adalah latihan mental yang unik yang tidak bisa Anda dapatkan dari bahasa lain. Namun, Anda harus menolak coba-coba dan mulai mempelajari bahasa dengan cara yang cermat dan hati-hati sebelum Anda dapat sepenuhnya menghargai aspek ini.
Tetapi mungkin realisasi paling penting yang dapat diberikan C kepada Anda, sebagai bahasa yang kecil, adalah gagasan bahwa semua pemrograman bermuara pada data dan operasi . Anda mungkin ingin melihat hal-hal sebagai kelas modular dengan hierarki dan antarmuka dengan pengiriman virtual, atau nilai-nilai abadi yang elegan yang dioperasikan menggunakan fungsi matematika murni. Dan itu tidak masalah - tetapi C akan mengingatkan Anda bahwa itu semua hanya operasi data + . Ini adalah pola pikir yang berguna karena memungkinkan Anda untuk menurunkan beberapa hambatan mental.
sumber
Alasan mengapa C baik untuk belajar bukanlah karena ia mengajarkan prinsip apa pun . Ini mengajarkan Anda, bagaimana segala sesuatu bekerja .
C dapat dibandingkan dengan salah satu mobil tua yang bagus dari tahun 70an atau 80an, yang baru saja dibuat untuk dikendarai. Anda dapat memisahkannya, sekrup demi sekrup, dan memahami bagaimana masing-masing bagian bekerja, dan bagaimana ia bekerja bersama dengan bagian lain yang dapat Anda ambil di tangan Anda untuk melihatnya. Setelah Anda memahami semua bagian, Anda memiliki gambaran yang sangat jelas bagaimana keseluruhan beroperasi.
Bahasa modern lebih seperti mobil modern di mana mesinnya pada dasarnya adalah kotak hitam, terlalu rumit untuk dipahami oleh pemilik mobil biasa. Mobil-mobil itu dapat melakukan banyak hal, heck, pada hari-hari ini secara aktif belajar mengemudi sendiri. Dan dengan kerumitan dan kenyamanan itu, antarmuka pengguna telah dipindahkan jauh dari apa yang sebenarnya terjadi di mesin.
Ketika Anda belajar pemrograman dalam C, Anda bersentuhan dengan banyak sekrup dan mur yang terbuat dari komputer. Ini memungkinkan Anda untuk mengembangkan pemahaman tentang mesin itu sendiri. Sebagai contoh, ini memungkinkan Anda untuk memahami mengapa itu bukan ide yang baik untuk membangun string panjang seperti ini:
(Saya harap, ini adalah Java yang benar, saya belum menggunakannya dalam beberapa saat ...) Dari contoh kode ini, tidak jelas mengapa loop memiliki kompleksitas kuadratik. Tapi itulah masalahnya, dan itu adalah alasan mengapa kode ini akan berhenti bekerja ketika Anda memiliki beberapa juta komponen kecil untuk digabungkan. Pemrogram C yang berpengalaman tahu langsung di mana masalahnya, dan kemungkinan akan menghindari menulis kode seperti itu di tempat pertama.
sumber
for(int i = 0; i < strlen(s); i++)
dalam C, loop juga akan memiliki kompleksitas kuadratik, dan sama tidak jelasnya seperti pada contoh Java Anda ;-)Ada bahasa yang lebih baik daripada C untuk mempelajari "prinsip-prinsip di balik pemrograman", terutama prinsip-prinsip teoretis, tetapi C mungkin baik untuk mempelajari beberapa hal praktis dan penting tentang kerajinan tangan. Jawaban greyfade adalah benar benar, tetapi IMHO ada lebih banyak yang dapat Anda pelajari dari C daripada bagaimana mengelola memori sendiri. Sebagai contoh,
cara membuat program dengan penanganan kesalahan lengkap tanpa adanya pengecualian
cara membuat struktur dalam program tanpa dukungan bahasa untuk orientasi objek
bagaimana menangani data tanpa adanya struktur data seperti daftar dinamis yang cukup besar, kamus atau abstraksi string yang berguna
bagaimana menghindari kesalahan umum seperti limpahan array bahkan ketika lingkungan kompiler atau run time tidak memperingatkan Anda secara otomatis
cara membuat solusi generik tanpa dukungan bahasa untuk templat atau generik
dan apakah saya menyebutkan Anda bisa belajar mengelola memori sendiri, tentu saja? ;-)
Selain itu, dengan mempelajari C, Anda akan belajar dari mana persamaan sintaksis C ++, Java, C #, Objective C berasal.
Pada tahun 2005, Joel Spolsky menulis rekomendasi untuk belajar C sebelum bahasa tingkat tinggi lainnya. Argumennya adalah
"Anda tidak akan pernah bisa membuat kode efisien dalam bahasa tingkat yang lebih tinggi."
"Anda tidak akan pernah bisa bekerja pada kompiler dan sistem operasi, yang merupakan beberapa pekerjaan pemrograman terbaik di sekitar."
"Kamu tidak akan pernah dipercaya untuk membuat arsitektur untuk proyek skala besar"
"Jika Anda tidak dapat menjelaskan mengapa
while(*s++ = *t++);
menyalin string, atau jika itu bukan hal yang paling alami di dunia untuk Anda, yah, Anda pemrograman berdasarkan takhayulTentu saja, apa yang ditulisnya pasti dapat diperdebatkan, tetapi banyak argumennya yang masih berlaku hingga saat ini.
sumber
Dua abstraksi dasar komputasi adalah mesin Turing dan kalkulus Lambda, dan C adalah cara untuk bereksperimen dengan pandangan komputasi mesin Turing: kebanyakan suksesi tindakan tingkat rendah yang darinya muncul hasil yang diinginkan. Tetapi Anda harus ingat bahwa C hadir dengan model komputasinya sendiri. Jadi, belajar C akan mengajari Anda perincian tingkat rendah dari mesin abstrak C, yang semakin berbeda dari arsitektur sebenarnya. Salah satu hal pertama yang saya diajarkan di C adalah untuk tidak pernah mencoba mengakali kompiler dengan menerapkan trik "pintar", dan tampaknya kecenderungannya adalah semakin banyak optimisasi dalam kompiler. Seperti dalam bahasa tingkat tinggi lainnya, ketika Anda menulis dalam C, kompiler memahami apa yang Anda harapkan dilakukan pada mesin C abstrak dan mewujudkannya pada perangkat keras yang sebenarnya,
Jadi yang saya maksud adalah bahwa belajar C tidak selalu akan memberi Anda gambaran yang baik tentang apa yang sebenarnya terjadi pada perangkat keras. "C dekat dengan mesin" harus dipahami sebagai "lebih dekat daripada kebanyakan bahasa tingkat tinggi". Mempelajari arsitektur perangkat lunak secara langsung akan lebih bermanfaat jika Anda menginginkan gambaran yang lebih akurat tentang "cara kerjanya".
Di sisi lain, belajar C dapat membiasakan Anda dengan pemrograman sistem, tipe tingkat rendah, pointer dan alokasi memori tertentu. Sedangkan untuk mempelajari algoritma dan struktur data, saya tidak memiliki keuntungan untuk mempelajarinya dalam bahasa C daripada bahasa lain.
sumber
Ini adalah pertanyaan yang berakhir sangat terbuka, mungkin tidak memberikan jawaban konklusif. Anda dapat mempelajari hampir semua hal dalam setiap bahasa asalkan Anda memahami internal kerangka kerja bahasa. C memaksa Anda untuk memahami detail yang lebih rendah karena itu terutama dirancang untuk menulis sistem operasi. Bahkan setelah bertahun-tahun, itu masih menjadi salah satu bahasa yang paling banyak digunakan terutama berkat sistem tertanam dan proyek sumber terbuka. Jadi, pertanyaannya adalah apa yang ingin Anda pelajari? Dan di domain mana?
sumber