Baca SICP dan pelajari Skema, dan ide praktis tipe data abstrak . Maka coding dalam C itu mudah (karena dengan SICP, sedikit C, dan sedikit PHP, Ruby, dll ... pemikiran Anda akan cukup luas, dan Anda akan mengerti bahwa pemrograman berorientasi objek mungkin bukan gaya terbaik di semua kasus, tetapi hanya untuk beberapa jenis program). Hati-hati dengan alokasi memori dinamis C , yang mungkin merupakan bagian tersulit. The C99 atau C11 standar bahasa pemrograman dan yang C standar perpustakaan sebenarnya sangat miskin (tidak tahu tentang TCP atau direktori!), Dan Anda akan sering perlu beberapa perpustakaan eksternal atau antarmuka (misalnyaPOSIX , libcurl untuk perpustakaan klien HTTP, libonion untuk perpustakaan server HTTP, GMPlib untuk bignum, beberapa perpustakaan seperti libunistring untuk UTF-8, dll ...).
"Objek" Anda sering kali dalam C struct
-s terkait , dan Anda menentukan set fungsi yang beroperasi pada mereka. Untuk fungsi pendek atau sangat sederhana, pertimbangkan untuk mendefinisikannya, dengan yang relevan struct
, seperti static inline
pada beberapa file header foo.h
menjadi #include
-d di tempat lain.
Perhatikan bahwa pemrograman berorientasi objek bukan satu-satunya paradigma pemrograman . Dalam beberapa kesempatan, paradigma lain bermanfaat ( pemrograman fungsional à la Ocaml atau Haskell atau bahkan Skema atau Commmon Lisp, pemrograman logika à la Prolog, dll. ... Baca juga blog J.Pitrat tentang deklarasi kecerdasan buatan). Lihat buku Scott: Bahasa Pemrograman Pragmatik
Sebenarnya, seorang programmer di C, atau di Ocaml, biasanya tidak ingin kode dalam gaya pemrograman berorientasi objek. Tidak ada alasan untuk memaksa diri Anda memikirkan benda-benda saat itu tidak berguna.
Anda akan mendefinisikan beberapa struct
dan fungsi-fungsi yang beroperasi pada mereka (seringkali melalui pointer). Anda bisa memerlukan beberapa serikat yang ditandai (sering, a struct
dengan anggota tag, sering beberapa enum
, dan beberapa union
di dalam), dan Anda mungkin menemukan berguna untuk memiliki anggota array yang fleksibel di akhir beberapa struct
-s Anda .
Lihat di dalam kode sumber dari beberapa perangkat lunak gratis yang ada di C (lihat github & sourceforge
untuk menemukan beberapa). Mungkin, menginstal dan menggunakan distribusi Linux akan berguna: dibuat hampir hanya dari perangkat lunak bebas, ia memiliki kompiler perangkat lunak C gratis yang hebat ( GCC , Dentang / LLVM ) dan alat pengembangan. Lihat juga Pemrograman Linux Lanjut jika Anda ingin mengembangkan untuk Linux.
Jangan lupa untuk mengompilasi dengan semua peringatan dan info debug, misalnya gcc -Wall -Wextra -g
-terutama selama fase pengembangan & debugging- dan belajar menggunakan beberapa alat, misalnya valgrind untuk memburu kebocoran memori , gdb
debugger, dll. Berhati-hatilah untuk memahami dengan baik apa yang tidak terdefinisi perilaku dan sangat menghindarinya (ingat bahwa suatu program dapat memiliki beberapa UB dan kadang-kadang tampaknya "bekerja").
Ketika Anda benar-benar membutuhkan konstruksi berorientasi objek (khususnya warisan ), Anda dapat menggunakan pointer ke struktur terkait dan fungsi. Anda bisa memiliki mesin vtable Anda sendiri , masing-masing memiliki "objek" dimulai dengan pointer ke pointer struct
fungsi yang mengandung. Anda mengambil keuntungan dari kemampuan untuk melemparkan tipe pointer ke tipe pointer lain (dan fakta bahwa Anda bisa melemparkan dari yang struct super_st
berisi jenis bidang yang sama dengan yang memulai a struct sub_st
untuk meniru warisan). Perhatikan bahwa C cukup untuk mengimplementasikan sistem objek yang cukup canggih - khususnya dengan mengikuti beberapa konvensi -, seperti diperlihatkan GObject (dari GTK / Gnome).
Ketika Anda benar-benar membutuhkan penutupan , Anda akan sering meniru mereka dengan panggilan balik , dengan konvensi bahwa setiap fungsi yang menggunakan panggilan balik dilewatkan baik oleh pointer fungsi dan beberapa data klien (dikonsumsi oleh pointer fungsi ketika memanggil itu). Anda juga dapat memiliki (secara konvensional) closure-like struct
-s Anda sendiri (mengandung beberapa pointer fungsi dan nilai-nilai tertutup).
Karena C adalah bahasa tingkat yang sangat rendah, penting untuk mendefinisikan dan mendokumentasikan konvensi Anda sendiri (terinspirasi oleh praktik dalam program C lainnya), khususnya tentang manajemen memori, dan mungkin beberapa konvensi penamaan juga. Sangat berguna untuk memiliki beberapa gagasan tentang arsitektur set instruksi . Jangan lupa bahwa sebuah C compiler dapat melakukan banyak optimasi pada kode Anda (jika Anda bertanya kepada), sehingga tidak peduli terlalu banyak tentang melakukan mikro-optimasi dengan tangan, cuti bahwa untuk compiler Anda (gcc -Wall -O2
untuk kompilasi dioptimalkan dirilis perangkat lunak). Jika Anda peduli tentang tolok ukur dan kinerja mentah, Anda harus mengaktifkan pengoptimalan (setelah program Anda didebug).
Jangan lupa bahwa kadang - kadang metaprogramming berguna . Cukup sering, perangkat lunak besar yang ditulis dalam C berisi beberapa skrip atau program ad-hoc untuk menghasilkan beberapa kode C yang digunakan di tempat lain (dan Anda mungkin juga memainkan beberapa trik preprosesor C yang kotor , misalnya X-macro ). Ada beberapa generator program C yang berguna (mis. Yacc atau gnu bison untuk menghasilkan parser, gperf untuk menghasilkan fungsi hash yang sempurna, dll ...). Pada beberapa sistem (terutama Linux & POSIX) Anda bahkan dapat menghasilkan beberapa kode C saat runtime dalam generated-001.c
file, kompilasi ke objek bersama dengan menjalankan beberapa perintah (sepertigcc -O -Wall -shared -fPIC generated-001.c -o generated-001.so
) saat runtime, secara dinamis memuat objek yang dibagikan menggunakan dlopen& dapatkan penunjuk fungsi dari nama menggunakan dlsym . Saya melakukan trik-trik semacam itu dalam MELT (bahasa khusus domain mirip Lisp yang mungkin berguna bagi Anda, karena memungkinkan penyesuaian dari kompiler GCC ).
Waspadai konsep dan teknik pengumpulan sampah ( penghitungan referensi sering kali merupakan teknik untuk mengelola memori dalam C, dan itu adalah bentuk buruk pengumpulan sampah yang tidak menangani dengan baik dengan referensi melingkar ; Anda bisa memiliki petunjuk lemah untuk membantu tentang itu, tapi mungkin rumit). Pada beberapa kesempatan, Anda mungkin mempertimbangkan untuk menggunakan pengumpul sampah Boehm yang konservatif .
qux = foo.bar(baz)
menjadiqux = Foo_bar(foo, baz)
.