Bagaimana Prioritas Operator C Melanggar Kode Anda (Dan Cara Memperbaikinya)

5

Anda menulis apa yang Anda maksud. Kompiler membaca apa yang diinginkannya.

Jika Anda pernah melihat sebaris kode C dan yakin kode itu melakukan satu hal, lalu melihatnya melakukan sesuatu yang lain, Anda telah bertemu dengan prioritas operator. Ini bukan bug. Ini adalah fitur bahasa yang bahkan menggigit pengembang berpengalaman.

Ambil aritmatika sederhana ini:

x=5+3*6;

Kelas matematika mengatakan tambahkan dulu. C bilang tidak. Perkalian dan pembagian berada pada tingkat yang lebih tinggi daripada penjumlahan dan pengurangan. Kompiler mengalikan 3 dengan 6 terlebih dahulu. Lalu ditambah 5. X mendapat 23. Bukan 48. Anda baru saja kehilangan poin pada kuis. Atau lebih buruk lagi, penerapan produksi.

Kebingungan semakin dalam ketika Anda mencampurkan operator dengan sintaksis.

Lihatlah deklarasi ini:

karakter *a[10];

Apakah a merupakan penunjuk ke array 10 karakter? Atau apakah itu array yang terdiri dari 10 pointer ke karakter?

Tanpa mengetahui aturan prioritas spesifiknya, Anda hanya menebak-nebak. Di C, tanda kurung [] mengikat lebih erat daripada pointer *. Jadi ini adalah array yang terdiri dari 10 pointer ke karakter.

Ini penting karena C tidak diuraikan seperti bahasa Inggris. Ini diurai seperti hierarki yang kaku.

Anda dapat menulis kode yang terlihat benar tetapi gagal secara diam-diam karena diutamakan.

Pertimbangkan aritmatika penunjuk yang dicampur dengan akses struktur.

*pi = 10;

Ini tidak berjalan sesuai harapan. Operator titik . memiliki prioritas lebih tinggi daripada operator dereferensi *. Kompiler mencoba mengakses anggota i dari objek yang ditunjuk oleh p sebelum melakukan dereferensi p. Tapi p adalah sebuah pointer, bukan sebuah struct. Kompiler tersedak. Atau lebih buruk lagi, ia menafsirkan memori sedemikian rupa sehingga merusak data.

Anda harus memaksakan masalah ini.

(*p).i = 10;

Tanda kurung menang. Selalu.

Hirarki Operator

Kernighan dan Ritchie, arsitek C, menetapkan prioritas dalam teks klasik mereka. Tabel di bawah ini menunjukkan urutannya. Baris teratas adalah yang tertinggi. Bagian bawah adalah yang terendah.

  1. Tanda kurung () dan Berlangganan []
  2. Kiri ke kanan.
  3. Operator Unary ++, --, +, -, !, ~, (type), * (dereference), & (alamat), sizeof
  4. Kanan ke kiri.
  5. Perkalian *, /, %
  6. Kiri ke kanan.
  7. Aditif +, -
  8. Kiri ke kanan.
  9. Shift <<, >>
  10. Kiri ke kanan.
  11. Relasional <, <=, >, >=
  12. Kiri ke kanan.
  13. Kesetaraan ==, !=
  14. Kiri ke kanan.
  15. Bitwise DAN &
  16. Kiri ke kanan.
  17. XOR Bitwise ^