Setelah Bertahun-tahun, Dunia Masih Didukung oleh Pemrograman C

Diterbitkan: 2022-03-11

Banyak proyek C yang ada saat ini dimulai beberapa dekade yang lalu.

Pengembangan sistem operasi UNIX dimulai pada tahun 1969, dan kodenya ditulis ulang dalam bahasa C pada tahun 1972. Bahasa C sebenarnya dibuat untuk memindahkan kode kernel UNIX dari perakitan ke bahasa tingkat yang lebih tinggi, yang akan melakukan tugas yang sama dengan baris kode yang lebih sedikit. .

Pengembangan database Oracle dimulai pada tahun 1977, dan kodenya ditulis ulang dari perakitan ke C pada tahun 1983. Ini menjadi salah satu database paling populer di dunia.

Pada tahun 1985 Windows 1.0 dirilis. Meskipun kode sumber Windows tidak tersedia untuk umum, telah dinyatakan bahwa kernelnya sebagian besar ditulis dalam C, dengan beberapa bagian dalam perakitan. Pengembangan kernel Linux dimulai pada tahun 1991, dan juga ditulis dalam C. Tahun berikutnya, dirilis di bawah lisensi GNU dan digunakan sebagai bagian dari Sistem Operasi GNU. Sistem operasi GNU sendiri mulai menggunakan bahasa pemrograman C dan Lisp, sehingga banyak komponennya yang ditulis dalam bahasa C.

Tetapi pemrograman C tidak terbatas pada proyek yang dimulai beberapa dekade yang lalu, ketika bahasa pemrograman tidak sebanyak hari ini. Banyak proyek C masih dimulai hari ini; ada beberapa alasan bagus untuk itu.

Bagaimana Dunia Didukung oleh C?

Terlepas dari prevalensi bahasa tingkat tinggi, C terus memberdayakan dunia. Berikut ini adalah beberapa sistem yang digunakan oleh jutaan orang dan diprogram dalam bahasa C.

Microsoft Windows

Kernel Microsoft Windows sebagian besar dikembangkan dalam bahasa C, dengan beberapa bagian dalam bahasa rakitan. Selama beberapa dekade, sistem operasi yang paling banyak digunakan di dunia, dengan sekitar 90 persen pangsa pasar, telah didukung oleh kernel yang ditulis dalam C.

Linux

Linux juga sebagian besar ditulis dalam C, dengan beberapa bagian dalam perakitan. Sekitar 97 persen dari 500 superkomputer paling kuat di dunia menjalankan kernel Linux. Ini juga digunakan di banyak komputer pribadi.

Mac

Komputer Mac juga didukung oleh C, karena kernel OS X sebagian besar ditulis dalam C. Setiap program dan driver di Mac, seperti pada komputer Windows dan Linux, berjalan pada kernel yang didukung C.

Seluler

Kernel iOS, Android, dan Windows Phone juga ditulis dalam C. Kernel tersebut hanyalah adaptasi seluler dari kernel Mac OS, Linux, dan Windows yang ada. Jadi smartphone yang Anda gunakan setiap hari berjalan pada kernel C.

Kernel Sistem Operasi Ditulis dalam C

Database

Database paling populer di dunia, termasuk Oracle Database, MySQL, MS SQL Server, dan PostgreSQL, dikodekan dalam C (tiga yang pertama sebenarnya keduanya dalam C dan C++).

Basis data digunakan di semua jenis sistem: keuangan, pemerintahan, media, hiburan, telekomunikasi, kesehatan, pendidikan, ritel, jejaring sosial, web, dan sejenisnya.

Basis Data Didukung oleh C

Film 3D

Film 3D dibuat dengan aplikasi yang umumnya ditulis dalam C dan C++. Aplikasi tersebut harus sangat efisien dan cepat, karena menangani sejumlah besar data dan melakukan banyak perhitungan per detik. Semakin efisien mereka, semakin sedikit waktu yang dibutuhkan artis dan animator untuk menghasilkan gambar film, dan semakin banyak uang yang dihemat perusahaan.

Sistem Tertanam

Bayangkan suatu hari Anda bangun dan pergi berbelanja. Jam alarm yang membangunkan Anda kemungkinan diprogram dalam C. Kemudian Anda menggunakan microwave atau pembuat kopi untuk membuat sarapan Anda. Mereka juga sistem tertanam dan karena itu mungkin diprogram dalam C. Anda menyalakan TV atau radio saat Anda makan sarapan Anda. Itu juga sistem tertanam, ditenagai oleh C. Saat Anda membuka pintu garasi dengan remote control, Anda juga menggunakan sistem tertanam yang kemungkinan besar diprogram dalam C.

Kemudian Anda masuk ke mobil Anda. Jika memiliki fitur berikut, juga diprogram dalam C:

  • transmisi otomatis
  • sistem deteksi tekanan ban
  • sensor (oksigen, suhu, level oli, dll.)
  • memori untuk kursi dan pengaturan cermin.
  • tampilan dasbor
  • rem anti-lock
  • kontrol stabilitas otomatis
  • kendali pelayaran
  • kontrol iklim
  • kunci anti-anak
  • entri tanpa kunci
  • kursi berpemanas
  • kontrol airbag

Anda pergi ke toko, memarkir mobil Anda dan pergi ke mesin penjual otomatis untuk mendapatkan soda. Bahasa apa yang mereka gunakan untuk memprogram mesin penjual otomatis ini? Mungkin C. Kemudian Anda membeli sesuatu di toko. Mesin kasir juga diprogram dalam C. Dan kapan Anda membayar dengan kartu kredit Anda? Anda dapat menebaknya: pembaca kartu kredit, sekali lagi, kemungkinan diprogram dalam C.

Semua perangkat itu adalah sistem tertanam. Mereka seperti komputer kecil yang memiliki mikrokontroler/mikroprosesor di dalamnya yang menjalankan program, juga disebut firmware, pada perangkat yang disematkan. Program itu harus mendeteksi penekanan tombol dan bertindak sesuai, dan juga menampilkan informasi kepada pengguna. Misalnya, jam alarm harus berinteraksi dengan pengguna, mendeteksi tombol apa yang ditekan pengguna dan, terkadang, berapa lama tombol itu ditekan, dan memprogram perangkat yang sesuai, sambil menampilkan informasi yang relevan kepada pengguna. Sistem rem anti-lock pada mobil, misalnya, harus mampu mendeteksi penguncian tiba-tiba ban dan bertindak untuk melepaskan tekanan pada rem untuk waktu yang singkat, membuka kuncinya, dan dengan demikian mencegah penyaradan yang tidak terkendali. Semua perhitungan tersebut dilakukan oleh sistem tertanam yang diprogram.

Meskipun bahasa pemrograman yang digunakan pada sistem tertanam dapat bervariasi dari merek ke merek, mereka paling sering diprogram dalam bahasa C, karena fitur bahasa fleksibilitas, efisiensi, kinerja, dan kedekatan dengan perangkat keras.

Sistem Tertanam Sering Ditulis dalam C

Mengapa Bahasa Pemrograman C Masih Digunakan?

Ada banyak bahasa pemrograman, hari ini, yang memungkinkan pengembang menjadi lebih produktif daripada dengan C untuk berbagai jenis proyek. Ada bahasa tingkat yang lebih tinggi yang menyediakan perpustakaan built-in yang jauh lebih besar yang menyederhanakan bekerja dengan JSON, XML, UI, halaman web, permintaan klien, koneksi database, manipulasi media, dan sebagainya.

Namun terlepas dari itu, ada banyak alasan untuk percaya bahwa pemrograman C akan tetap aktif untuk waktu yang lama.

Dalam bahasa pemrograman satu ukuran tidak cocok untuk semua. Berikut adalah beberapa alasan mengapa C tidak terkalahkan, dan hampir wajib, untuk aplikasi tertentu.

Portabilitas dan Efisiensi

C hampir merupakan bahasa rakitan portabel . Ini sedekat mungkin dengan mesin sementara hampir tersedia secara universal untuk arsitektur prosesor yang ada. Setidaknya ada satu kompiler C untuk hampir setiap arsitektur yang ada. Dan saat ini, karena binari yang sangat dioptimalkan yang dihasilkan oleh kompiler modern, bukanlah tugas yang mudah untuk meningkatkan outputnya dengan perakitan tulisan tangan.

Portabilitas dan efisiensinya sedemikian rupa sehingga "kompiler, pustaka, dan penerjemah bahasa pemrograman lain sering diimplementasikan dalam C". Bahasa yang ditafsirkan seperti Python, Ruby, dan PHP memiliki implementasi utama yang ditulis dalam C. Bahkan digunakan oleh kompiler untuk bahasa lain untuk berkomunikasi dengan mesin. Misalnya, C adalah bahasa perantara yang mendasari Eiffel dan Forth. Ini berarti, alih-alih menghasilkan kode mesin untuk setiap arsitektur yang akan didukung, kompiler untuk bahasa tersebut hanya menghasilkan kode C perantara, dan kompiler C menangani pembuatan kode mesin.

C juga telah menjadi lingua franca untuk berkomunikasi antar pengembang. Seperti yang dikatakan Alex Allain, Manajer Teknik Dropbox dan pencipta Cprogramming.com:

C adalah bahasa yang bagus untuk mengekspresikan ide-ide umum dalam pemrograman dengan cara yang nyaman bagi kebanyakan orang. Selain itu, banyak prinsip yang digunakan dalam C – misalnya, argc dan argv untuk parameter baris perintah, serta konstruksi loop dan tipe variabel – akan muncul dalam banyak bahasa lain yang Anda pelajari sehingga Anda dapat berbicara untuk orang-orang bahkan jika mereka tidak tahu C dengan cara yang umum untuk Anda berdua.

Manipulasi Memori

Akses alamat memori arbitrer dan aritmatika pointer adalah fitur penting yang membuat C sangat cocok untuk pemrograman sistem (sistem operasi dan sistem tertanam).

Pada batas hardware/software, sistem komputer dan mikrokontroler memetakan periferal dan pin I/O mereka ke dalam alamat memori. Aplikasi sistem harus membaca dan menulis ke lokasi memori khusus tersebut untuk berkomunikasi dengan dunia. Jadi kemampuan C untuk memanipulasi alamat memori arbitrer sangat penting untuk pemrograman sistem.

Mikrokontroler dapat dirancang, misalnya, sehingga byte dalam alamat memori 0x40008000 akan dikirim oleh penerima/pemancar asinkron universal (atau UART, komponen perangkat keras umum untuk berkomunikasi dengan periferal) setiap kali nomor bit 4 dari alamat 0x40008001 disetel ke 1, dan setelah Anda menyetel bit itu, bit itu akan secara otomatis tidak disetel oleh periferal.

Ini akan menjadi kode untuk fungsi C yang mengirim satu byte melalui UART itu:

 #define UART_BYTE *(char *)0x40008000 #define UART_SEND *(volatile char *)0x40008001 |= 0x08 void send_uart(char byte) { UART_BYTE = byte; // write byte to 0x40008000 address UART_SEND; // set bit number 4 of address 0x40008001 }

Baris pertama dari fungsi akan diperluas menjadi:

 *(char *)0x40008000 = byte;

Baris ini memberitahu kompiler untuk menginterpretasikan nilai 0x40008000 sebagai pointer ke char , kemudian ke dereference (memberikan nilai yang ditunjuk oleh) pointer itu (dengan operator * paling kiri) dan akhirnya untuk menetapkan nilai byte ke pointer dereferenced itu. Dengan kata lain: tulis nilai variabel byte ke alamat memori 0x40008000 .

Baris berikutnya akan diperluas menjadi:

 *(volatile char *)0x40008001 |= 0x08;

Pada baris ini, kita melakukan operasi OR bitwise pada nilai di alamat 0x40008001 dan nilai 0x08 ( 00001000 dalam biner, yaitu, 1 dalam bit nomor 4), dan menyimpan hasilnya kembali ke alamat 0x40008001 . Dengan kata lain: kita set bit 4 dari byte yang ada di alamat 0x40008001. Kami juga menyatakan bahwa nilai pada alamat 0x40008001 bersifat volatile . Ini memberi tahu kompiler bahwa nilai ini dapat dimodifikasi oleh proses di luar kode kita, sehingga kompiler tidak akan membuat asumsi apa pun tentang nilai di alamat itu setelah menulisnya. (Dalam hal ini, bit ini tidak disetel oleh perangkat keras UART tepat setelah kami menyetelnya oleh perangkat lunak.) Informasi ini penting untuk pengoptimal kompilator. Jika kita melakukan ini di dalam for loop, misalnya, tanpa menentukan bahwa nilainya tidak stabil, kompilator mungkin menganggap nilai ini tidak pernah berubah setelah disetel, dan lewati eksekusi perintah setelah loop pertama.

Penggunaan Sumber Daya Deterministik

Fitur bahasa umum yang tidak dapat diandalkan oleh pemrograman sistem adalah pengumpulan sampah, atau bahkan hanya alokasi dinamis untuk beberapa sistem tertanam. Aplikasi yang disematkan sangat terbatas dalam waktu dan sumber daya memori. Mereka sering digunakan untuk sistem waktu nyata, di mana panggilan non-deterministik ke pengumpul sampah tidak dapat dilakukan. Dan jika alokasi dinamis tidak dapat digunakan karena kurangnya memori, sangat penting untuk memiliki mekanisme lain dari manajemen memori, seperti menempatkan data di alamat khusus, seperti yang diizinkan oleh pointer C. Bahasa yang sangat bergantung pada alokasi dinamis dan pengumpulan sampah tidak akan cocok untuk sistem dengan sumber daya terbatas.

Ukuran Kode

C memiliki runtime yang sangat kecil. Dan jejak memori untuk kodenya lebih kecil daripada kebanyakan bahasa lain.

Jika dibandingkan dengan C++, misalnya, biner yang dihasilkan C yang masuk ke perangkat yang disematkan berukuran sekitar setengah dari ukuran biner yang dihasilkan oleh kode C++ yang serupa. Salah satu penyebab utama untuk itu adalah dukungan pengecualian.

Pengecualian adalah alat hebat yang ditambahkan oleh C++ melalui C, dan, jika tidak dipicu dan diimplementasikan dengan cerdas, mereka praktis tidak memiliki overhead waktu eksekusi (tetapi dengan biaya peningkatan ukuran kode).

Mari kita lihat contoh di C++:

 // Class A declaration. Methods defined somewhere else; class A { public: A(); // Constructor ~A(); // Destructor (called when the object goes out of scope or is deleted) void myMethod(); // Just a method }; // Class B declaration. Methods defined somewhere else; class B { public: B(); // Constructor ~B(); // Destructor void myMethod(); // Just a method }; // Class C declaration. Methods defined somewhere else; class C { public: C(); // Constructor ~C(); // Destructor void myMethod(); // Just a method }; void myFunction() { A a; // Constructor aA() called. (Checkpoint 1) { B b; // Constructor bB() called. (Checkpoint 2) b.myMethod(); // (Checkpoint 3) } // b.~B() destructor called. (Checkpoint 4) { C c; // Constructor cC() called. (Checkpoint 5) c.myMethod(); // (Checkpoint 6) } // c.~C() destructor called. (Checkpoint 7) a.myMethod(); // (Checkpoint 8) } // a.~A() destructor called. (Checkpoint 9)

Metode kelas A , B dan C didefinisikan di tempat lain (misalnya di file lain). Oleh karena itu kompiler tidak dapat menganalisisnya dan tidak dapat mengetahui apakah mereka akan mengeluarkan pengecualian. Jadi itu harus bersiap untuk menangani pengecualian yang dilemparkan dari konstruktor, destruktor, atau panggilan metode lainnya. Destruktor tidak boleh melempar (praktik yang sangat buruk), tetapi pengguna tetap bisa melempar, atau mereka bisa melempar secara tidak langsung dengan memanggil beberapa fungsi atau metode (secara eksplisit atau implisit) yang melempar pengecualian.

Jika salah satu panggilan di myFunction mengeluarkan pengecualian, mekanisme pelepasan tumpukan harus dapat memanggil semua destruktor untuk objek yang sudah dibuat. Satu implementasi untuk mekanisme pelepasan tumpukan akan menggunakan alamat pengirim dari panggilan terakhir dari fungsi ini untuk memverifikasi "nomor pos pemeriksaan" dari panggilan yang memicu pengecualian (ini adalah penjelasan sederhana). Ini dilakukan dengan memanfaatkan fungsi autogenerated tambahan (semacam tabel pencarian) yang akan digunakan untuk pelepasan tumpukan jika pengecualian dilemparkan dari badan fungsi itu, yang akan mirip dengan ini:

 // Possible autogenerated function void autogeneratedStackUnwindingFor_myFunction(int checkpoint) { switch (checkpoint) { // case 1 and 9: do nothing; case 3: b.~B(); goto destroyA; // jumps to location of destroyA label case 6: c.~C(); // also goes to destroyA as that is the next line destroyA: // label case 2: case 4: case 5: case 7: case 8: a.~A(); } }

Jika pengecualian dilemparkan dari pos pemeriksaan 1 dan 9, tidak ada objek yang perlu dihancurkan. Untuk pos pemeriksaan 3, b dan a harus dimusnahkan. Untuk pos pemeriksaan 6, c dan a harus dimusnahkan. Dalam semua kasus, perintah pemusnahan harus dihormati. Untuk checkpoint 2, 4, 5, 7, dan 8, hanya objek a perlu dimusnahkan.

Fungsi tambahan ini menambah ukuran kode. Ini adalah bagian dari overhead ruang yang ditambahkan C++ ke C. Banyak aplikasi yang disematkan tidak mampu menyediakan ruang ekstra ini. Oleh karena itu, kompiler C++ untuk sistem tertanam sering kali memiliki tanda untuk menonaktifkan pengecualian. Menonaktifkan pengecualian di C++ tidak gratis, karena Perpustakaan Template Standar sangat bergantung pada pengecualian untuk menginformasikan kesalahan. Menggunakan skema yang dimodifikasi ini, tanpa pengecualian, memerlukan lebih banyak pelatihan bagi pengembang C++ untuk mendeteksi kemungkinan masalah atau menemukan bug.

Dan, kita berbicara tentang C++, bahasa yang prinsipnya adalah: "Anda tidak membayar untuk apa yang tidak Anda gunakan." Peningkatan ukuran biner ini menjadi lebih buruk untuk bahasa lain yang menambahkan overhead tambahan dengan fitur lain yang sangat berguna tetapi tidak dapat diberikan oleh sistem tertanam. Meskipun C tidak memberi Anda penggunaan fitur tambahan ini, C memungkinkan jejak kode yang jauh lebih ringkas daripada bahasa lain.

Alasan untuk Belajar C

C bukanlah bahasa yang sulit untuk dipelajari, jadi semua manfaat dari mempelajarinya akan cukup murah. Mari kita lihat beberapa manfaatnya.

Bahasa pergaulan

Seperti yang telah disebutkan, C adalah lingua franca untuk pengembang. Banyak implementasi algoritme baru di buku atau di internet pertama kali (atau hanya) dibuat tersedia dalam bahasa C oleh penulisnya. Ini memberikan portabilitas maksimum yang mungkin untuk implementasi. Saya telah melihat programmer berjuang di internet untuk menulis ulang algoritma C ke bahasa pemrograman lain karena dia tidak tahu konsep dasar C.

Ketahuilah bahwa C adalah bahasa lama dan tersebar luas, sehingga Anda dapat menemukan semua jenis algoritme yang ditulis dalam C di seluruh web. Oleh karena itu, Anda kemungkinan besar akan mendapat manfaat dari mengetahui bahasa ini.

Memahami Mesin (Berpikir dalam C)

Ketika kita mendiskusikan perilaku bagian kode tertentu, atau fitur tertentu dari bahasa lain, dengan rekan kerja, kita akhirnya "berbicara dalam C:" Apakah bagian ini meneruskan "penunjuk" ke objek atau menyalin seluruh objek? Mungkinkah ada "pemeran" yang terjadi di sini? Dan seterusnya.

Kami jarang mendiskusikan (atau memikirkan) tentang instruksi perakitan yang dijalankan oleh sebagian kode ketika menganalisis perilaku sebagian kode bahasa tingkat tinggi. Sebaliknya, ketika mendiskusikan apa yang sedang dilakukan mesin, kita berbicara (atau berpikir) dengan cukup jelas dalam bahasa C.

Selain itu, jika Anda tidak dapat berhenti dan berpikir seperti itu tentang apa yang Anda lakukan, Anda mungkin berakhir dengan pemrograman dengan semacam takhayul tentang bagaimana (secara ajaib) sesuatu dilakukan.

Berpikir Seperti Mesin dengan C

Bekerja di Banyak Proyek C yang Menarik

Banyak proyek menarik, dari server database besar atau kernel sistem operasi, hingga aplikasi kecil yang tertanam yang bahkan dapat Anda lakukan di rumah untuk kepuasan dan kesenangan pribadi Anda, dilakukan di C. Tidak ada alasan untuk berhenti melakukan hal-hal yang mungkin Anda sukai karena satu alasan bahwa Anda tidak tahu bahasa pemrograman lama dan kecil, tetapi kuat dan terbukti waktu seperti C.

Kerjakan Proyek Keren dengan C

Kesimpulan

Illuminati tidak menjalankan dunia. programmer C melakukannya.
Menciak

Bahasa pemrograman C sepertinya tidak memiliki tanggal kedaluwarsa. Kedekatannya dengan perangkat keras, portabilitas yang hebat, dan penggunaan sumber daya yang deterministik membuatnya ideal untuk pengembangan tingkat rendah untuk hal-hal seperti kernel sistem operasi dan perangkat lunak yang disematkan. Keserbagunaan, efisiensi, dan kinerjanya yang baik menjadikannya pilihan yang sangat baik untuk perangkat lunak manipulasi data dengan kompleksitas tinggi, seperti database atau animasi 3D. Fakta bahwa banyak bahasa pemrograman saat ini lebih baik daripada C untuk tujuan penggunaannya tidak berarti bahwa mereka mengalahkan C di semua bidang. C masih tak tertandingi ketika kinerja menjadi prioritas.

Dunia berjalan pada perangkat bertenaga C. Kami menggunakan perangkat ini setiap hari apakah kami menyadarinya atau tidak. C adalah masa lalu, masa kini, dan, sejauh yang bisa kita lihat, masih masa depan untuk banyak bidang perangkat lunak.

Terkait: Cara Mempelajari Bahasa C dan C++: Daftar Utama