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?
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?
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.
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.
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.)
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.
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.
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 takhayul
Tentu saja, apa yang ditulisnya pasti dapat diperdebatkan, tetapi banyak argumennya yang masih berlaku hingga saat ini.
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.
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?