C tidak memiliki tipe boolean bawaan. Apa cara terbaik untuk menggunakannya di C?
C tidak memiliki tipe boolean bawaan. Apa cara terbaik untuk menggunakannya di C?
Jawaban:
Dari yang terbaik menjadi lebih buruk:
Opsi 1 (C99)
#include <stdbool.h>
pilihan 2
typedef enum { false, true } bool;
Opsi 3
typedef int bool;
enum { false, true };
Opsi 4
typedef int bool;
#define true 1
#define false 0
Jika Anda ragu-ragu, lanjutkan dengan # 1!
<stdbool.h> boolkompiler yang dipilih mungkin lebih cocok untuk tujuan yang diinginkan dari nilai boolean daripada menggunakan int(yaitu kompiler dapat memilih untuk mengimplementasikan yang boolberbeda dari pada int). Mungkin juga menghasilkan pengecekan tipe yang lebih ketat pada waktu kompilasi, jika Anda beruntung.
intuntuk bool? Itu sia-sia. Gunakan unsigned char. Atau menggunakan C builtin _Bool.
Beberapa pemikiran tentang boolean di C:
Saya cukup tua sehingga saya hanya menggunakan ints polos sebagai tipe boolean saya tanpa typedefs atau definisi khusus atau enums untuk nilai benar / salah. Jika Anda mengikuti saran saya di bawah ini untuk tidak pernah membandingkan terhadap konstanta boolean, maka Anda hanya perlu menggunakan 0/1 untuk menginisialisasi flag. Namun, pendekatan semacam itu mungkin dianggap terlalu reaksioner di zaman modern ini. Dalam hal ini, seseorang harus menggunakan <stdbool.h>karena setidaknya memiliki manfaat standar.
Apa pun yang disebut konstanta boolean, gunakan hanya untuk inisialisasi. Jangan pernah menulis sesuatu seperti itu
if (ready == TRUE) ...
while (empty == FALSE) ...
Ini selalu bisa diganti dengan yang lebih jelas
if (ready) ...
while (!empty) ...
Perhatikan bahwa ini sebenarnya dapat secara wajar dan dimengerti dibaca dengan keras.
Beri nama positif variabel boolean Anda, yaitu fullsebagai ganti notfull. Yang terakhir mengarah ke kode yang sulit dibaca dengan mudah. Membandingkan
if (full) ...
if (!full) ...
dengan
if (!notfull) ...
if (notfull) ...
Kedua mantan pasangan membaca secara alami, sementara !notfullcanggung membaca bahkan seperti apa adanya, dan menjadi jauh lebih buruk dalam ekspresi boolean yang lebih kompleks.
Argumen Boolean umumnya harus dihindari. Pertimbangkan fungsi yang didefinisikan seperti ini
void foo(bool option) { ... }
Dalam tubuh fungsi, sangat jelas apa artinya argumen karena memiliki nama yang nyaman, dan mudah-mudahan bermakna. Tapi, situs panggilan terlihat seperti
foo(TRUE);
foo(FALSE):
Di sini, pada dasarnya tidak mungkin untuk mengatakan apa arti parameter tanpa selalu melihat definisi fungsi atau deklarasi, dan akan menjadi lebih buruk segera jika Anda menambahkan lebih banyak parameter boolean. Saya sarankan juga
typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);
atau
#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }
Dalam kedua kasus, situs panggilan sekarang terlihat seperti
foo(OPT_ON);
foo(OPT_OFF);
dimana pembaca setidaknya memiliki kesempatan untuk memahami tanpa mengeruk definisi foo.
a == bberhasil?
adan bmenghitung dari nol, saya akan merekomendasikan a > 0 == b > 0. Jika Anda bersikeras untuk mengambil keuntungan dari kebenaran nilai bukan nol yang sewenang-wenang, !!varmenghasilkan nilai boolean 0/1 yang setara dengan var, sehingga Anda bisa menulis !!a == !!b, meskipun beberapa pembaca akan menganggapnya membingungkan.
!a == !bjuga cukup untuk menguji kesetaraan, bukan nol menjadi nol, dan nol menjadi satu.
!!a"konversi non-boolean ke nilai kebenaran yang setara", sedangkan saya akan membaca !a"secara logis membalikkan variabel boolean a". Secara khusus, saya akan mencari beberapa alasan spesifik inversi logis diinginkan.
Boolean dalam C adalah integer: nol untuk false dan non-nol untuk true.
Lihat juga tipe data Boolean , bagian C, C ++, Objective-C, AWK .
Ini adalah versi yang saya gunakan:
typedef enum { false = 0, true = !false } bool;
Karena false hanya memiliki satu nilai, tetapi true logis dapat memiliki banyak nilai, tetapi teknik menetapkan true menjadi apa yang akan digunakan oleh kompiler untuk kebalikan dari false.
Ini menangani masalah seseorang yang mengkode sesuatu yang akan menjadi seperti ini:
if (true == !false)
Saya pikir kita semua akan setuju bahwa itu bukan praktik yang baik, tetapi untuk satu kali biaya melakukan "true =! False" kita menghilangkan masalah itu.
[EDIT] Pada akhirnya saya menggunakan:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
untuk menghindari tabrakan nama dengan skema lain yang mendefinisikan truedanfalse . Namun konsepnya tetap sama.
[EDIT] Untuk menampilkan konversi integer ke boolean:
mybool somebool;
int someint = 5;
somebool = !!someint;
Yang pertama (paling kanan)! mengkonversi bilangan nol ke nol, kemudian bilangan bulat kedua (paling kiri)! mengkonversi 0 ke amyfalse nilai. Saya akan meninggalkannya sebagai latihan bagi pembaca untuk mengkonversi bilangan bulat nol.
[EDIT] Ini adalah gaya saya untuk menggunakan pengaturan eksplisit dari nilai dalam enum ketika nilai spesifik diperlukan bahkan jika nilai defaultnya akan sama. Contoh: Karena false harus nol saya gunakan false = 0,daripadafalse,
true, falsedan booldisorot di sebagian besar IDE karena mereka adalah nilai enum dan typedef, sebagai lawan dari #defines, yang jarang disorot oleh sintaks.
gcc -ansi -pedantic -Walltidak memberikan peringatan, jadi saya percaya gcc; Jika ini berhasil bahkan untuk c89itu harus bekerja c99juga.
!hanya dapat mengembalikan nilai 0dan 1, jadi true = !falseakan selalu memberikan nilai 1. Metode ini tidak memberikan keamanan ekstra typedef enum { false, true } bool;.
if(!value)), tetapi pengecualian itu tidak berlaku dalam kasus khusus ini.
Jika Anda menggunakan kompiler C99, ia memiliki dukungan bawaan untuk tipe bool:
#include <stdbool.h>
int main()
{
bool b = false;
b = true;
}
Hal pertama yang pertama. C, yaitu ISO / IEC 9899 telah memiliki tipe boolean selama 19 tahun sekarang . Itu adalah waktu yang jauh lebih lama daripada yang diharapkan dari karir pemrograman C dengan bagian-bagian amatir / akademik / profesional digabungkan ketika mengunjungi pertanyaan ini . Milik saya memang melampaui itu mungkin hanya 1-2 tahun. Ini berarti bahwa selama waktu rata-rata pembaca telah belajar apa pun tentang C, C sebenarnya telah memiliki tipe data boolean .
Untuk tipe data #include <stdbool.h>,, dan gunakan true, falsedan bool. Atau jangan memasukkannya, dan gunakan _Bool, 1dan 0sebagai gantinya.
Ada berbagai praktik berbahaya yang dipromosikan dalam jawaban lain untuk utas ini. Saya akan mengatasinya:
typedef int bool;
#define true 1
#define false 0
Ini tidak-tidak, karena pembaca biasa - yang memang belajar C dalam 19 tahun itu - akan mengharapkan yang boolmengacu pada tipe data aktual bool dan akan berperilaku sama, tetapi tidak! Sebagai contoh
double a = ...;
bool b = a;
Dengan C99 bool/ _Bool, bakan diatur ke false iff a adalah nol, dan truesebaliknya. C11 6.3.1.2p1
- Ketika nilai skalar apa pun dikonversi menjadi
_Bool, hasilnya adalah 0 jika nilainya sebanding dengan 0; jika tidak, hasilnya adalah 1. 59)Catatan kaki
59) NaNs tidak membandingkan sama dengan 0 dan dengan demikian dikonversi ke 1.
Dengan typedefdi tempat, doubleakan dipaksa ke int- jika nilai ganda tidak dalam kisaranint , perilaku tidak terdefinisi .
Secara alami hal yang sama berlaku untuk if true dan falsedinyatakan dalamenum .
Apa yang lebih berbahaya adalah menyatakan
typedef enum bool {
false, true
} bool;
karena sekarang semua nilai selain 1 dan 0 tidak valid, dan jika nilai seperti itu diberikan ke variabel jenis itu, perilaku akan sepenuhnya tidak terdefinisi .
Karena itu jika Anda tidak dapat menggunakan C99 karena alasan yang tidak dapat dijelaskan, untuk variabel boolean Anda harus menggunakan:
intdan nilai 0dan1 apa adanya ; dan hati-hati lakukan konversi domain dari nilai-nilai lain ke ini dengan negasi ganda!!BOOL, TRUEdan FALSE!intatau unsigned intuntuk menahan enumerasi, tetapi saya tidak tahu apa-apa dalam Standar yang akan menyebabkan enumerasi berperilaku sebagai selain integer Tipe.
typedef enum {
false = 0,
true
} t_bool;
!0 = 1oleh standar C, dan !a = 0untuk nilai bukan nol dari a. Masalahnya adalah bahwa setiap non-nol dianggap benar. Jadi jika adan bkeduanya "benar", itu tidak selalu berarti `a == b`.
C memiliki tipe boolean: bool (setidaknya selama 10 (!) Tahun terakhir)
Sertakan stdbool.h dan true / false akan berfungsi seperti yang diharapkan.
boolharus makro yang diperluas _Bool. Perbedaannya penting karena Anda bisa #undefmakro (dan itu diizinkan, setidaknya sebagai ukuran transisi), tetapi Anda tidak untypedefbisa mengetik. Itu tidak mengubah dorongan utama dari komentar pertama Anda.
Apa pun yang bukan nol dievaluasi benar dalam operasi boolean, jadi Anda bisa saja
#define TRUE 1
#define FALSE 0
dan gunakan konstanta.
Hanya pelengkap jawaban lain dan klarifikasi, jika Anda diizinkan menggunakan C99.
+-------+----------------+-------------------------+--------------------+
| Name | Characteristic | Dependence in stdbool.h | Value |
+-------+----------------+-------------------------+--------------------+
| _Bool | Native type | Don't need header | |
+-------+----------------+-------------------------+--------------------+
| bool | Macro | Yes | Translate to _Bool |
+-------+----------------+-------------------------+--------------------+
| true | Macro | Yes | Translate to 1 |
+-------+----------------+-------------------------+--------------------+
| false | Macro | Yes | Translate to 0 |
+-------+----------------+-------------------------+--------------------+
Beberapa preferensi saya:
_Boolatau bool? Keduanya baik-baik saja, tetapi boolterlihat lebih baik daripada kata kunci_Bool .booldan _Booladalah: falseatau true. Menetapkan 0atau 1bukannya falseatau truevalid, tetapi lebih sulit untuk membaca dan memahami aliran logika.Beberapa info dari standar:
_BoolTIDAK unsigned int, tetapi merupakan bagian dari grup tipe integer yang tidak ditandai . Cukup besar untuk menampung nilai 0atau1 .bool truedanfalse tetapi tentu saja itu bukan ide yang baik. Kemampuan ini dianggap usang dan akan dihapus di masa depan._Boolatau bool, jika nilai skalar sama 0atau membandingkannya dengan 0itu 0, jika tidak hasilnya adalah 1: _Bool x = 9; 9dikonversi menjadi 1ketika ditugaskan x._Booladalah 1 byte (8 bit), biasanya programmer tergoda untuk mencoba menggunakan bit lainnya, tetapi tidak disarankan, karena satu-satunya jaminan yang diberikan adalah bahwa hanya satu bit yang digunakan untuk menyimpan data, tidak seperti tipe charyang memiliki 8 bit tersedia.Anda dapat menggunakan arang, atau wadah nomor kecil lainnya untuknya.
Kode semu
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
int), karena pada beberapa arsitektur Anda mendapatkan hasil kinerja yang signifikan karena harus membongkar / menutupi pemeriksaan pada variabel-variabel ini.
Anda bisa menggunakan _Bool, tetapi nilai balik harus berupa bilangan bulat (1 untuk true, 0 untuk false). Namun, disarankan untuk memasukkan dan menggunakan bool seperti dalam C ++, seperti yang dikatakan dalam balasan ini dari forum daniweb , serta jawaban ini , dari pertanyaan stackoverflow lainnya:
_Bool: tipe boolean C99. Menggunakan _Bool secara langsung hanya disarankan jika Anda mempertahankan kode lawas yang sudah mendefinisikan makro untuk bool, true, atau false. Kalau tidak, makro-makro itu distandarkan di header. Sertakan header itu dan Anda dapat menggunakan bool seperti yang Anda lakukan di C ++.
Ekspresi bersyarat dianggap benar jika tidak nol, tetapi standar C mengharuskan operator logika itu sendiri mengembalikan 0 atau 1.
@Tom: #define TRUE! FALSE buruk dan sama sekali tidak ada gunanya. Jika file header masuk ke kode C ++ yang dikompilasi, maka itu dapat menyebabkan masalah:
void foo(bool flag);
...
int flag = TRUE;
foo(flag);
Beberapa kompiler akan menghasilkan peringatan tentang konversi bool int =>. Terkadang orang menghindari ini dengan melakukan:
foo(flag == TRUE);
untuk memaksa ekspresi menjadi bool C ++. Tetapi jika Anda #menentukan BENAR! SALAH, Anda berakhir dengan:
foo(flag == !0);
yang akhirnya melakukan perbandingan int-to-bool yang dapat memicu peringatan itu.
Jika Anda menggunakan C99 maka Anda dapat menggunakan _Booljenisnya. Tidak #includeperlu. Anda perlu memperlakukannya seperti integer, meskipun, di mana 1adalah truedan 0adalahfalse .
Anda kemudian dapat mendefinisikan TRUEdan FALSE.
_Bool this_is_a_Boolean_var = 1;
//or using it with true and false
#define TRUE 1
#define FALSE 0
_Bool var = TRUE;
#include <stdbool.h>dan penggunaan bool, truedan falseseperti standar ingin Anda.
Inilah yang saya gunakan:
enum {false, true};
typedef _Bool bool;
_Bool adalah tipe bawaan C. Ini dimaksudkan untuk nilai boolean.
Anda cukup menggunakan #definearahan sebagai berikut:
#define TRUE 1
#define FALSE 0
#define NOT(arg) (arg == TRUE)? FALSE : TRUE
typedef int bool;
Dan gunakan sebagai berikut:
bool isVisible = FALSE;
bool isWorking = TRUE;
isVisible = NOT(isVisible);
dan seterusnya
argdan ekspresi secara keseluruhan: #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE). Namun, akan lebih baik untuk menguji kepalsuan (itu akan memberikan jawaban yang benar bahkan jika argitu 23 bukannya 0 atau 1:. #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)Tetapi seluruh ekspresi dapat dikurangi menjadi #define NOT(arg) (!(arg)), tentu saja, yang menghasilkan hasil yang sama.