Menu

Boolean di C: stdbool.h, _Bool, dan Nilai Kebenaran

C tidak punya tipe boolean sampai C99. Nol berarti false, selain itu true, hasil perbandingan bertipe int, dan stdbool.h menambahkan bool, true, dan false di atasnya. Ditambah bug = vs == yang lahir dari desain ini.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Selama 27 tahun pertamanya, C tidak punya tipe boolean. Itu bukan kelalaian, melainkan keputusan desain yang akibatnya langsung kamu temui di hari pertama, beserta satu bug terkenal yang muncul langsung darinya.

Nol Berarti False, Selain Itu True

Aturan kondisi di C tidak mengenal nilai true/false khusus. if, while, for, &&, ||, dan ! semuanya mengajukan satu pertanyaan saja: apakah nilai ini nol?

Bilangan negatif bernilai true. Pecahan bernilai true. Pointer yang tidak null bernilai true. Hanya nol, dalam tipe apa pun, yang bernilai false.

Karena itulah kode C penuh dengan pola yang terlihat singkat sekali sampai kamu tahu aturannya:

if (count)            /* if count is not zero */
if (!count)           /* if count is zero */
if (p)                /* if p is not NULL */
if (!strcmp(a, b))    /* if the strings are equal - strcmp returns 0 for a match */

Yang terakhir itu sering menjebak. strcmp mengembalikan 0 kalau kedua string sama, jadi "sama" terbaca sebagai "tidak" di dalam if. Menulis if (strcmp(a, b) == 0) lebih jelas dan hasilnya persis sama.

Perbandingan Menghasilkan int

Perbandingan di C bukan jenis ekspresi khusus. Hasilnya adalah int biasa dengan nilai 1 atau 0, dan kamu bisa mencetaknya, menyimpannya, atau memakainya dalam aritmetika:

Operator ! bekerja dengan cara yang sama: hasilnya 1 kalau operandnya nol dan 0 kalau tidak. Jadi !!x adalah pola klasik untuk mengubah nilai apa pun menjadi tepat 0 atau 1.

bool, true, dan false (C99)

C99 menambahkan tipe boolean sungguhan bernama _Bool, plus sebuah header yang memberinya nama yang mudah dibaca:

<stdbool.h> sangat kecil: ia mendefinisikan bool sebagai _Bool, true sebagai 1, dan false sebagai 0. Hanya itu isi header-nya. Tetapi memakainya membuat maksudmu terlihat jelas, sesuatu yang tidak pernah bisa dilakukan int flag = 1;.

_Bool punya satu perilaku yang benar-benar berbeda: ia hanya menyimpan 0 atau 1. Meng-assign nilai bukan nol apa pun akan dikonversi menjadi tepat 1:

printf tetap tidak punya %b untuk boolean. Cetak dengan %d, atau ubah sendiri menjadi teks:

Di C23 semuanya jadi lebih sederhana lagi: bool, true, dan false menjadi kata kunci sungguhan, jadi include itu tidak lagi diperlukan. Sebagian besar kode saat ini masih menargetkan C17, jadi tetap tulis #include <stdbool.h>.

Mengembalikan Boolean dari Fungsi

Di sinilah bool paling jelas menunjukkan gunanya:

Tipe kembalian bool memberi tahu pemanggil apa arti nilainya. Tipe kembalian int dari fungsi bernama check_file bisa berupa boolean, jumlah, atau kode error, dan menurut konvensi library C sering kali yang ketiga, di mana 0 berarti sukses. Menyebutkan tipenya menghilangkan tebak-tebakan itu.

Bug = vs ==

Karena assignment adalah ekspresi yang menghasilkan nilai yang di-assign, dan karena nilai bukan nol apa pun bernilai true, kode ini bisa dikompilasi:

Dua hal salah sekaligus. Kondisinya meng-assign 5 ke x sehingga nilai lamanya hilang, lalu menguji 5, yang bukan nol, sehingga cabangnya dijalankan. Secara default program ini tidak memunculkan error maupun peringatan.

Lebih buruk lagi, versi dengan 0 tidak pernah menjalankan cabangnya:

if (found = 0) { /* never taken - and found is now 0 */ }

Ada tiga cara bertahan, diurutkan dari yang paling berguna:

Kompilasi dengan peringatan. -Wall menangkapnya:

warning: suggest parentheses around assignment used as truth value

Membuat peringatan menjadi nol adalah perbaikan yang sebenarnya, dan biayanya hanya satu flag.

Tulis konstantanya lebih dulu. "Kondisi Yoda" membuat salah ketik itu menjadi error kompilasi:

if (5 == x)   /* correct */
if (5 = x)    /* error: not an lvalue - the compiler stops you */

Sebagian tim menyukainya dan sebagian lagi menganggapnya sulit dibaca. Kedua pendapat itu masuk akal, tetapi cara ini memang berhasil.

Sengaja dan jelas saat kamu memang bermaksud begitu. Assignment di dalam kondisi benar-benar berguna untuk membaca input:

int c;
while ((c = getchar()) != EOF) { ... }

Tanda kurung ekstra di sekitar c = getchar() wajib karena urutan prioritas operator, dan sekaligus menandakan bahwa assignment itu disengaja. Itulah polanya: kalau assignment di dalam kondisimu tidak terlihat seperti itu, kemungkinan besar itu salah ketik.

Kesalahan Umum dengan Boolean

Membandingkan dengan true. if (flag == true) berfungsi dengan stdbool.h, tetapi langsung rusak begitu flag adalah int yang berisi 42, karena 42 == 1 bernilai false. Tulis if (flag).

Perbandingan berantai. if (0 < x < 10) selalu bernilai true: 0 < x menghasilkan 0 atau 1, dan keduanya lebih kecil dari 10. Tulis if (x > 0 && x < 10).

Operator bitwise, bukan logika. & dan | bukan && dan ||. Keduanya tidak melakukan short-circuit, dan keduanya menggabungkan bit:

Kedua operand bernilai "true", tetapi a & b adalah 0. Memakai & padahal maksudmu && menghasilkan kondisi yang hanya salah untuk nilai tertentu, jenis bug yang paling sulit ditemukan.

Membandingkan float dengan tanda sama dengan. if (0.1 + 0.2 == 0.3) bernilai false. Bandingkan dengan toleransi; lihat tipe data untuk alasannya.

Pertanyaan yang sering diajukan

Apakah C punya tipe boolean?

Sejak C99, ya: _Bool adalah tipe bawaan, dan dengan meng-include <stdbool.h> kamu mendapat penulisan yang lebih ramah, yaitu bool, true, dan false. Sebelum C99 tidak ada boolean sama sekali. Program memakai int dengan 0 untuk false dan 1 untuk true, dan cara ini masih berfungsi serta masih sering dipakai.

Apa yang dianggap true di C?

Nilai apa pun yang bukan nol. 1, -5, 0.01, dan pointer yang tidak null semuanya bernilai true di dalam kondisi; hanya 0, 0.0, dan pointer null yang bernilai false. Tidak ada pemeriksaan boolean tersendiri: if (x) hanya menguji apakah x bukan nol.

Bagaimana cara memakai bool di C?

Tambahkan #include <stdbool.h>, lalu bool ready = true; berjalan seperti yang kamu harapkan. Di balik layar, bool adalah _Bool, yang hanya menyimpan 0 atau 1: meng-assign nilai bukan nol apa pun akan menyimpan tepat 1.

Apa perbedaan = dan == di C?

= meng-assign, == membandingkan. if (x = 5) meng-assign 5 ke x lalu menguji 5, yang bukan nol, sehingga cabangnya selalu dijalankan. if (x == 5) menguji kesamaan. Bentuk pertama bisa dikompilasi tanpa error, karena itulah -Wall dan kebiasaan menulis if (5 == x) ada.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai