Apakah saya perlu belajar C untuk memahami cara kerja komputer?

Saya sering mendengar orang menyarankan belajar C. untuk memahami kinerja komputer. Apakah itu ide yang bagus? Apakah kamu yakin Saya akan segera menguraikan kesimpulan artikel, hanya untuk kejelasan mutlak:

  • C bukan cara komputer bekerja.
  • Saya tidak berpikir kebanyakan orang berbicara secara harfiah, jadi itu tidak masalah.
  • Memahami konteks berarti bahwa belajar C untuk alasan ini mungkin masih masuk akal, tergantung pada tujuan Anda.

Saya berencana untuk menulis dua artikel lagi dengan penjelasan yang lebih terperinci dari kesimpulan, tetapi ini sudah cukup. Tambahkan tautan di sini saat artikel keluar.

Saya sering mendengar dari orang-orang ini:

Dengan mempelajari C, Anda dapat memahami cara kerja komputer.

Saya tidak berpikir bahwa idenya awalnya salah, tetapi memiliki beberapa keberatan. Jika Anda mengingatnya, itu bisa menjadi strategi yang layak untuk mempelajari hal-hal baru dan penting. Namun, saya jarang melihat orang membahas reservasi ini secara rinci, jadi saya menulis artikel ini untuk memberikan, menurut pendapat saya, konteks yang sangat diperlukan ... Jika Anda berpikir tentang belajar C untuk memahami cara kerja komputer Anda, maka artikel ini adalah untuk Anda. Saya harap dia membantu Anda mengetahuinya.

Sebelum kita benar-benar memulai, saya ingin mengatakan satu hal lagi: jika Anda ingin belajar C, maka belajarlah! Belajar itu bagus. Belajar C telah menjadi sangat penting bagi pemahaman saya tentang komputasi dan karier saya. Mempelajari bahasa ini dan tempatnya dalam sejarah bahasa pemrograman akan menjadikan Anda seorang programmer yang lebih baik. Anda tidak perlu alasan apa pun. Belajar hal-hal hanya demi belajar. Artikel ini dimaksudkan sebagai pedoman untuk memahami kebenaran, tidak membahas apakah akan belajar C.

Pertama-tama, kepada siapa ide ini umumnya direkomendasikan. Jika Anda mencoba "mencari tahu cara kerja komputer," maka tidak perlu dikatakan bahwa saat ini Anda tidak memahami ini. Programmer mana yang tidak mengerti cara kerja komputer? Saya pada dasarnya melihat bahwa perasaan ini berasal dari orang-orang yang sebagian besar memprogram dalam bahasa "scripting" yang diketik secara dinamis seperti Ruby, Python, atau JavaScript. Mereka seharusnya "tidak tahu bagaimana komputer bekerja" karena bahasa-bahasa ini bekerja di dalam mesin virtual, di mana hanya semantik masalah mesin virtual. Pada akhirnya, seluruh ide mesin virtual adalah untuk menyediakan portabilitas. Tujuannya bukan untuk bergantung pada peralatan yang dijalankan VM.

Hanya ada satu masalah: C juga berfungsi di dalam mesin virtual.

Mesin Abstrak C


Dari spesifikasi C99 , bagian 5.1.2.3, “Eksekusi Program”:

Deskripsi semantik dalam Standar Internasional ini menjelaskan perilaku mesin abstrak yang masalah pengoptimalannya tidak relevan.

Menurut pendapat saya, ini adalah hal yang paling penting untuk dipahami ketika belajar C. Bahasa tidak "menggambarkan bagaimana komputer bekerja", tetapi menggambarkan bagaimana "mesin C abstrak" bekerja. Semua hal penting lainnya mengikuti dari konsep ini.

Satu lagi catatan: di sini saya memilih C99, yang bukan standar C. terbaru Mengapa? Yah, MSVC memiliki ... dukungan bahasa C yang menarik , dan saya pengguna Windows akhir-akhir ini. Ya, Anda dapat menjalankan clang dan gcc di Windows. Tidak ada perbedaan besar antara C89, C99 dan C11 tentang apa yang kita bicarakan. Pada titik tertentu, Anda harus memilih. Versi yang saya sebutkan di sini mencakup beberapa perubahan pada spesifikasi aslinya.

Anda mungkin pernah mendengar ungkapan lain dalam ceramah C Anda: "C adalah assembler portabel." Jika Anda berpikir tentang frasa ini, Anda akan memahami bahwa jika ini benar, maka C tidak dapat sesuai dengan operasi komputer: ada banyak komputer berbeda dengan arsitektur yang berbeda. Jika C seperti assembler yang berjalan pada komputer yang berbeda dengan arsitektur yang berbeda, maka C tidak dapat berfungsi secara bersamaan persis seperti masing-masing komputer ini. Dia harus menyembunyikan detailnya, kalau tidak dia tidak akan portabel!

Namun demikian, saya pikir fakta ini tidak masalah, karena orang hampir tidak secara harfiah mengacu pada "C adalah cara kerja komputer." Sebelum kembali ke ini, mari kita bicara tentang mesin C abstrak, dan mengapa banyak yang tampaknya tidak memahami aspek C.

Digresi: mengapa orang salah?


Saya hanya bisa berbicara tentang pengalaman saya, walaupun pasti itu tidak unik.

Saya belajar GW-BASIC, lalu C, lalu C ++, lalu Jawa. Saya mendengar tentang Jawa sebelum saya mulai menulisnya sekitar tahun 1999, empat tahun setelah itu muncul. Pemasaran pada waktu itu secara aktif membandingkan Java dan C ++, itu berfokus pada JVM sebagai platform, dan pada kenyataan bahwa model mesin membedakannya dari C ++, dan karenanya C. Sun Microsystems tidak lagi ada, tetapi cermin rilis pers mengingatkan kita:

Aplikasi Java adalah platform independen; Anda hanya perlu melakukan porting mesin virtual Java ke setiap platform. Karena berfungsi sebagai juru bahasa antara komputer pengguna dan aplikasi Java. Aplikasi yang ditulis dalam lingkungan Java dapat bekerja di mana saja, sehingga tidak perlu lagi mem-port aplikasi ke berbagai platform.

Moto utamanya adalah "Menulis sekali, jalankan di mana-mana." Dua kalimat ini menjadi bagaimana saya (dan banyak lainnya) memahami Java, dan bagaimana ia berbeda dari C ++. Java memiliki interpreter, mesin virtual Java. Tidak ada mesin virtual di C ++.

Dengan pemasaran yang begitu kuat, "mesin virtual" di benak banyak orang telah menjadi identik dengan "runtime besar dan / atau penerjemah." Bahasa tanpa fitur ini terlalu terikat pada komputer tertentu dan memerlukan porting karena mereka tidak benar-benar platform independen. Alasan utama Java ada adalah perubahan dalam cacat C ++ ini.

"Lingkungan runtime", "mesin virtual" dan "mesin abstrak" adalah kata-kata yang berbeda untuk konsep dasar yang sama. Tetapi sejak itu mereka menerima konotasi yang berbeda karena ada sedikit perbedaan dalam implementasi ide-ide ini.

Saya pribadi percaya bahwa pemasaran tahun 1995 ini adalah alasan mengapa pemrogram masih salah memahami sifat C.

Jadi, apakah pernyataan ini salah? Mengapa Sun Microsystems menghabiskan jutaan dan jutaan dolar untuk mempromosikan kebohongan? Jika C juga didasarkan pada mesin abstrak yang menawarkan portabilitas lintas-platform, mengapa kita membutuhkan Java? Saya pikir ini adalah kunci untuk memahami apa yang sebenarnya dimaksud orang ketika mereka mengatakan "C adalah cara kerja komputer."

Apa yang sebenarnya orang maksud?


Meskipun C bekerja dalam konteks mesin virtual, C masih berbeda secara signifikan dari bahasa mirip Java. Sun tidak berbohong. Untuk memahami, Anda perlu tahu kisah C.

Pada tahun 1969, Bell Labs menulis sistem operasi komputer dalam bahasa assembly. Pada tahun 1970, ia dijuluki UNIX. Seiring waktu, Bell Labs membeli semakin banyak komputer baru, termasuk PDP-11.

Ketika tiba saatnya untuk port Unix ke PDP-11, mereka memutuskan untuk menggunakan bahasa tingkat yang lebih tinggi, yang merupakan ide yang cukup radikal pada saat itu. Bayangkan hari ini saya akan memberi tahu Anda: "Saya akan menulis OS di Jawa" - Anda mungkin akan tertawa, meskipun gagasan itu bisa diwujudkan . Situasi (dalam pemahaman saya, saya tidak hidup saat itu) kira-kira sama. Kami menganggap bahasa yang disebut B, tetapi tidak mendukung beberapa fungsi yang dimiliki PDP-11, dan oleh karena itu mereka menciptakan penggantinya dengan menyebutnya "C", karena itu adalah huruf berikutnya dalam alfabet.

Tidak ada bahasa "A"; B berhasil BCPL (Bahasa Pemrograman Gabungan Dasar).

Pada tahun 1972, kompiler C pertama ditulis pada PDP-11 dan pada saat yang sama ditulis ulang UNIX menjadi C. Awalnya, mereka tidak memikirkan portabilitas, tetapi C memperoleh ketenaran, sehingga kompiler C porting ke sistem lain.

Pada tahun 1978, edisi pertama buku "Bahasa Pemrograman C" diterbitkan. Disebut “K&R”, sesuai dengan nama penulisnya, buku itu sama sekali tidak menyerupai spesifikasi, tetapi pada saat yang sama menggambarkan bahasa tersebut dengan cukup rinci, sebagai akibatnya orang lain juga mencoba menulis kompiler C. Kemudian “versi” ini akan disebut “K&R C”.

Saat UNIX dan C menyebar, keduanya porting ke banyak komputer. Di tahun 70-an dan 80-an, basis perangkat keras mereka terus tumbuh. Dengan cara yang sama bahwa C dibuat karena B tidak mendukung semua fungsi PDP-11, banyak kompiler menggunakan ekstensi bahasa. Karena hanya ada K&R dan bukan spesifikasi, ini dianggap dapat diterima selama ekstensi cukup dekat. Pada tahun 1983, kurangnya standarisasi menyebabkan masalah, jadi ANSI membentuk tim untuk menyiapkan spesifikasi. Pada tahun 1989, standar C89 keluar, kadang-kadang disebut "ANSI C".

Spesifikasi C mencoba menyatukan beragam implementasi ini pada berbagai perangkat keras. Dengan demikian, mesin C abstrak adalah semacam spesifikasi sekecil mungkin yang memungkinkan kode yang sama berfungsi sama di semua platform. Implementasi C dikompilasi, tidak ditafsirkan, sehingga tidak ada penerjemah, oleh karena itu tidak ada "VM" dalam arti 1995. Namun, program C ditulis pada komputer abstrak yang tidak ada ini, dan kemudian kode tersebut dikonversi menjadi assembler khusus ke komputer tertentu di mana program tersebut berjalan. Anda tidak dapat mengandalkan beberapa detail spesifik untuk menulis kode C portabel. Ini membuat penulisan portabel C sangat sulit karena Anda mungkin telah membuat asumsi platform khusus ketika menulis versi awal kode Anda.

Ini paling baik digambarkan dengan contoh. Salah satu tipe data utama dalam C adalah char , dari kata "karakter". Namun, mesin C abstrak tidak menentukan berapa banyak bit yang harus di char . Ya, tentukan, tetapi tidak dengan angka; itu menentukan ukuran CHAR_BIT , yang merupakan konstanta. Bagian 5.2.4.2.1 dari spesifikasi:

Nilai-nilai yang diberikan di bawah ini harus diganti dengan ekspresi konstan yang sesuai atau digunakan dalam arahan preprocessing #if ... Nilai-nilai dalam implementasi spesifik harus sama dengan atau lebih besar dalam besarnya (nilai absolut) dari yang diberikan di sini dengan tanda yang sama.

CHAR_BIT: 8

Dengan kata lain, Anda tahu bahwa char setidaknya 8 bit, tetapi implementasinya mungkin lebih besar. Untuk menyandikan "mesin C abstrak," CHAR_BIT harus digunakan sebagai ganti ukuran 8 saat memproses char . Tapi ini bukan semacam fungsi interpreter, seperti yang kita pikirkan tentang mesin virtual; ini adalah properti dari bagaimana kompiler menerjemahkan kode sumber menjadi kode mesin.

Ya, ada sistem di mana CHAR_BIT bukan 8 .

Dengan demikian, "mesin abstrak" ini, walaupun secara teknis ide yang sama dengan mesin virtual Java, lebih mungkin merupakan konstruksi kompilasi untuk mengelola kompiler ketika membuat kode assembler, daripada semacam pemeriksaan runtime atau properti. Jenis yang setara di Jawa adalah byte , yang selalu 8 bit, dan implementasi JVM ditugaskan dengan apa yang harus dilakukan pada platform dengan lebih banyak byte. (Tidak yakin apakah JVM bekerja di salah satu platform ini, tetapi begitulah seharusnya.) Mesin C abstrak dibuat sebagai pembungkus minimal untuk berbagai "perangkat keras", dan bukan sebagai semacam platform yang terbuat dari bahan padat yang ditulis dalam perangkat lunak untuk kode Anda.

Jadi, meskipun Sun secara teknis salah, dalam praktiknya mereka sedikit berarti dari apa yang mereka katakan, dan apa yang mereka maksud adalah benar. Hal yang sama dengan ungkapan "Belajar C untuk Memahami Cara Kerja Komputer".

Pelajari C untuk LEBIH BAIK Memahami Bagaimana Komputer Bekerja


Apa yang sebenarnya orang maksud? Dalam konteks "seandainya seorang rubist belajar C untuk memahami bagaimana komputer bekerja" - ini adalah saran untuk turun "ke tingkat besi". Artinya, tidak hanya untuk memahami bagaimana program Anda bekerja di dalam mesin virtual, tetapi juga bagaimana kombinasi dari program dan VM bekerja dalam konteks mesin itu sendiri.

Belajar C akan memberi Anda lebih banyak detail ini karena mesin abstrak jauh lebih dekat ke perangkat keras serta abstraksi dari sistem operasi. Bahasa C sangat berbeda dari bahasa tingkat tinggi, jadi belajar bahasa itu bisa mengajar banyak.

Tetapi penting untuk diingat bahwa C pada dasarnya adalah abstraksi perangkat keras, dan abstraksi tidak sempurna. Berhati-hatilah dengan apa yang dilakukan C atau cara kerjanya dengan mesin itu sendiri. Jika Anda terlalu dalam, Anda pasti akan menemukan perbedaan ini, yang dapat menyebabkan masalah. Sebagian besar sumber daya pelatihan untuk C, terutama hari ini, ketika peralatan menjadi lebih homogen, akan mempromosikan gagasan bahwa ini adalah cara komputer bekerja. Oleh karena itu, mungkin sulit bagi siswa untuk memahami apa yang terjadi di bawah tenda dan apa abstraksi yang diberikan oleh C.

Dalam diskusi ini, kami bahkan tidak menyentuh masalah lain. Misalnya, karena popularitas C yang sangat besar, perangkat keras menjadi lebih seragam karena cenderung bergerak ke arah semantik mesin abstrak C. Jika arsitektur Anda terlalu berbeda dari semantik C, program C dapat berjalan jauh lebih lambat daripada yang lain. dan kecepatan perangkat keras sering diukur dengan tes dalam C. Artikel ini sudah cukup lama ...

Untuk alasan ini, saya pikir versi yang lebih akurat dari pernyataan ini adalah "Dengan mempelajari C, Anda akan belajar lebih banyak tentang cara kerja komputer." Saya benar-benar berpikir bahwa perkenalan dengan C sangat berguna bagi banyak programmer, bahkan jika mereka sendiri tidak menulis C. Memperkenalkan C juga akan memberi Anda gambaran tentang sejarah industri kami.

Ada cara lain untuk menjelajahi topik ini; C secara inheren tidak dirancang untuk mempelajari komputer, tetapi itu adalah pilihan yang baik.

Ada begitu banyak yang harus dipelajari dalam pemrograman. Semoga sukses dalam perjalanan ini.

Source: https://habr.com/ru/post/id426993/


All Articles