Apa yang harus diketahui oleh seorang programmer C? [Tutup]
11
Apa saja konsep / teknik / fitur bahasa yang harus diketahui / disadari oleh setiap programmer C yang layak (tidak termasuk rekayasa perangkat lunak umum dan sejenisnya dan hanya fokus pada hal-hal spesifik C). Saya ingin tahu sehingga saya bisa mengisi beberapa celah yang mungkin dalam pengetahuan C.
Mulailah dengan pertanyaan C Stack Overflow dan lihat apakah ada sesuatu yang tidak Anda ketahui.
chrisaycock
3
Pemrogram AC mungkin harus tahu itu2 + 2 = 4
Edward Strange
21
Mereka harus tahu toko yang menjual sepatu anti peluru.
Adam Crossland
1
Ada ratusan buku yang ditulis tentang hal ini. Pertanyaan Anda benar-benar tidak jelas. Anda harus lebih spesifik untuk mendapatkan jawaban yang layak yang bukan hanya daftar barang. Dan melihat jawaban yang diambil sejauh ini dari pertanyaan ini saya akan berpikir itu perlu dikerjakan ulang atau ditutup.
Walter
2
Bahasa pemrograman lain?
Muhammad Alkarouri
Jawaban:
19
Khusus untuk C? Selain konstruksi standar yang umum untuk sebagian besar bahasa prosedural, saya harus mengatakan:
(ab) menggunakan preprosesor
linker vs compiler
Pointer Pointer Pointer!
Bagaimana array adalah pointer adalah array
Bagaimana string C bekerja, dan bagaimana mereka juga pointer dan array
Seberapa buruk penggunaan string C dapat menyebabkan buffer overflows
Bagaimana cara melemparkan apa saja ke apa saja (setelah semua hanya 1s dan 0s :))
Manajemen memori manual malloc / gratis
Stack vs Heap
Pointer aliasing, (mengapa ilegal di C99)
Berpikir tentang pengembangan dalam hal modul (file .h / .c) dengan satu set fungsi yang terbuka untuk publik alih-alih kelas ketat
Pemrogram AC harus tahu ... bahasa lain! ;-) Selalu bermanfaat untuk mengetahui konsep dari bahasa lain dari berbagai paradigma, seperti OOP, pemrograman fungsional, dan sebagainya.
Lebih serius lagi, melihat kontes pemrograman yang membingungkan itu menyenangkan dan, anehnya, pengalaman yang bagus juga.
Saya menyebutkan "buffer overflows" dalam komentar atas jawaban Pythagras, saya mungkin harus mengklarifikasi apa yang saya maksudkan sedikit. Dalam C, itu tidak cukup untuk mengetahui bahwa bekerja secara langsung dengan memori itu berbahaya - Anda juga harus memahami cara yang tepat di mana itu berbahaya. Saya tidak terlalu suka metafora "menembak diri sendiri" untuk semua kasus ini - sering kali, bukan Anda yang menarik pelatuknya, tetapi seringkali itu adalah aktor dengan minat yang bertentangan dengan Anda dan / atau pengguna Anda. .
Misalnya, dalam arsitektur dengan tumpukan menurun (arsitektur paling populer sesuai dengan tagihan ini - termasuk x86 dan ARM), saat Anda memanggil suatu fungsi, alamat pengirim untuk fungsi tersebut akan ditempatkan pada tumpukan setelah variabel lokal yang ditentukan dalam tubuh fungsi. Jadi jika Anda mendeklarasikan buffer sebagai variabel lokal, dan mengekspos variabel itu ke dunia luar tanpa memeriksa buffer overflow, seperti ini:
void myFn(void){char buf[256];
gets(buf);}
pengguna eksternal dapat mengirim Anda string yang menimpa alamat pengirim dari stack - pada dasarnya, ia dapat mengubah ide run-time program Anda dari grafik panggilan yang mengarah ke fungsi saat ini. Jadi pengguna memberi Anda sebuah string yang merupakan representasi biner dari beberapa kode yang dapat dieksekusi untuk arsitektur Anda, cukup bantalan untuk melimpahi tumpukan myFn, dan beberapa data tambahan untuk menimpa alamat pengirim untuk myFnmenunjukkan kode yang ia berikan kepada Anda. Jika ini terjadi, maka ketika myFnbiasanya akan kembali kontrol ke peneleponnya, ia akan bercabang ke kode yang disediakan pengguna jahat. Jika Anda menulis kode C (atau C ++) yang berpotensi diekspos ke pengguna yang tidak terpercaya, Anda perlu memahami vektor serangan ini. Anda harus memahami mengapa buffer overflow terhadap stack sering (tetapi tidak selalu) lebih mudah dieksploitasi daripada yang melawan heap, dan Anda harus memahami bagaimana memori di heap diletakkan (tidak terlalu banyak detail, tentu saja, tetapi Gagasan bahwa suatu malloc()daerah memiliki struktur kontrol yang mengelilinginya dapat membantu memahami mengapa program Anda macet di tempat lain malloc(), atau di free()).
C memaparkan Anda ke detail tingkat rendah tentang cara kerja mesin Anda, dan itu memberi Anda kontrol lebih langsung atas mesin Anda daripada bahasa yang diedit pengguna lain yang digunakan secara luas saat ini. Dengan kekuatan besar datang tanggung jawab besar - Anda benar-benar perlu memahami detail tingkat rendah agar dapat bekerja dengan C dengan aman dan efektif.
2 + 2 = 4
Jawaban:
Khusus untuk C? Selain konstruksi standar yang umum untuk sebagian besar bahasa prosedural, saya harus mengatakan:
sumber
Pahami pointer dan Anda akan memahami komputer.
sumber
Selain jawaban sempurna pythagras,
cara menulis (atau setidaknya membaca) deklarasi yang rumit, seperti
char (*(*funcs[4])())[10]
funcs adalah array [4] dari pointer ke fungsi yang mengembalikan pointer ke array [10] dari char
sumber
sumber
Pemrogram AC harus tahu ... bahasa lain! ;-) Selalu bermanfaat untuk mengetahui konsep dari bahasa lain dari berbagai paradigma, seperti OOP, pemrograman fungsional, dan sebagainya.
Lebih serius lagi, melihat kontes pemrograman yang membingungkan itu menyenangkan dan, anehnya, pengalaman yang bagus juga.
sumber
Saya menyebutkan "buffer overflows" dalam komentar atas jawaban Pythagras, saya mungkin harus mengklarifikasi apa yang saya maksudkan sedikit. Dalam C, itu tidak cukup untuk mengetahui bahwa bekerja secara langsung dengan memori itu berbahaya - Anda juga harus memahami cara yang tepat di mana itu berbahaya. Saya tidak terlalu suka metafora "menembak diri sendiri" untuk semua kasus ini - sering kali, bukan Anda yang menarik pelatuknya, tetapi seringkali itu adalah aktor dengan minat yang bertentangan dengan Anda dan / atau pengguna Anda. .
Misalnya, dalam arsitektur dengan tumpukan menurun (arsitektur paling populer sesuai dengan tagihan ini - termasuk x86 dan ARM), saat Anda memanggil suatu fungsi, alamat pengirim untuk fungsi tersebut akan ditempatkan pada tumpukan setelah variabel lokal yang ditentukan dalam tubuh fungsi. Jadi jika Anda mendeklarasikan buffer sebagai variabel lokal, dan mengekspos variabel itu ke dunia luar tanpa memeriksa buffer overflow, seperti ini:
pengguna eksternal dapat mengirim Anda string yang menimpa alamat pengirim dari stack - pada dasarnya, ia dapat mengubah ide run-time program Anda dari grafik panggilan yang mengarah ke fungsi saat ini. Jadi pengguna memberi Anda sebuah string yang merupakan representasi biner dari beberapa kode yang dapat dieksekusi untuk arsitektur Anda, cukup bantalan untuk melimpahi tumpukan
myFn
, dan beberapa data tambahan untuk menimpa alamat pengirim untukmyFn
menunjukkan kode yang ia berikan kepada Anda. Jika ini terjadi, maka ketikamyFn
biasanya akan kembali kontrol ke peneleponnya, ia akan bercabang ke kode yang disediakan pengguna jahat. Jika Anda menulis kode C (atau C ++) yang berpotensi diekspos ke pengguna yang tidak terpercaya, Anda perlu memahami vektor serangan ini. Anda harus memahami mengapa buffer overflow terhadap stack sering (tetapi tidak selalu) lebih mudah dieksploitasi daripada yang melawan heap, dan Anda harus memahami bagaimana memori di heap diletakkan (tidak terlalu banyak detail, tentu saja, tetapi Gagasan bahwa suatumalloc()
daerah memiliki struktur kontrol yang mengelilinginya dapat membantu memahami mengapa program Anda macet di tempat lainmalloc()
, atau difree()
).C memaparkan Anda ke detail tingkat rendah tentang cara kerja mesin Anda, dan itu memberi Anda kontrol lebih langsung atas mesin Anda daripada bahasa yang diedit pengguna lain yang digunakan secara luas saat ini. Dengan kekuatan besar datang tanggung jawab besar - Anda benar-benar perlu memahami detail tingkat rendah agar dapat bekerja dengan C dengan aman dan efektif.
sumber
Selain jawaban bagus lainnya, saya ingin menambahkan teknik pemrograman defensif ke dalam daftar.
Misalnya menggunakan menegaskan pada awal / akhir fungsi untuk memverifikasi kontrak.
sumber