Bisakah Anda menguraikan mengapa mereka adalah yang terbaik untuk pilihan terburuk?
Endolith
1
@ endolith Penjajaran, optimisasi dan cara untuk menyimpan <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.
blubberdiblub
1
Kenapa digunakan intuntuk bool? Itu sia-sia. Gunakan unsigned char. Atau menggunakan C builtin _Bool.
user12211554
@NoBody Menggunakan tipe yang lebih kecil dapat menghemat memori, tetapi mungkin tidak membuatnya lebih cepat. Seringkali, lebih cepat menggunakan ukuran kata asli prosesor alih-alih ukuran yang lebih kecil karena dapat memerlukan kompiler untuk membuat sedikit pergeseran untuk menyelaraskannya dengan benar
Ted Klein Bergman
241
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
Dan bagaimana Anda membandingkan dua variabel untuk kesetaraan? Jangan pernah menggunakan konstanta boolean bekerja dengan baik, tetapi itu tidak menyelesaikan masalah ketika membandingkan dengan yang tidak konstan.
Baruch
Maafkan saya, tapi saya tidak mengerti pertanyaannya. Apakah Anda bertanya bagaimana saya membandingkan dua variabel boolean untuk kesetaraan? Jika demikian, tidak a == bberhasil?
Dale Hagglund
5
@ Kenji Apa yang Anda katakan itu benar, meskipun saya percaya bahwa menggunakan nilai selain yang setara dengan benar hampir selalu merupakan ide yang buruk. Jadi, dalam contoh Anda, dengan asumsi 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.
Dale Hagglund
3
!a == !bjuga cukup untuk menguji kesetaraan, bukan nol menjadi nol, dan nol menjadi satu.
ryanpattison
5
@ rpattiso Anda memang benar, tentu saja, tapi saya rasa saya akan membaca !!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.
Dale Hagglund
88
Boolean dalam C adalah integer: nol untuk false dan non-nol untuk true.
Ia bekerja dengan baik dengan operator logis juga (&& dan ||).
Vultrao
74
Ini adalah versi yang saya gunakan:
typedefenum{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.
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,
Juga manfaat lain untuk menggunakan enums adalah integrasi IDE - true, falsedan booldisorot di sebagian besar IDE karena mereka adalah nilai enum dan typedef, sebagai lawan dari #defines, yang jarang disorot oleh sintaks.
Penasaran: Mengabaikan apakah itu benar-benar berfungsi atau tidak, apakah valid C (99+) untuk mengizinkan enum untuk referensi nilai sebelumnya dalam enumerasi yang sama ?
@ tgm1024 gcc -ansi -pedantic -Walltidak memberikan peringatan, jadi saya percaya gcc; Jika ini berhasil bahkan untuk c89itu harus bekerja c99juga.
yyny
1
"Karena false hanya memiliki satu nilai, tetapi true logical dapat memiliki banyak nilai, tetapi teknik menetapkan true sebagai apa yang akan digunakan oleh kompiler untuk kebalikan dari false." Operator negasi !hanya dapat mengembalikan nilai 0dan 1, jadi true = !falseakan selalu memberikan nilai 1. Metode ini tidak memberikan keamanan ekstra typedef enum { false, true } bool;.
user694733
1
Yang paling awal saya temukan adalah dari C90 (6.3.3.3 operator aritmatika unary): "Hasil operator negasi logis! Adalah 0 jika nilai operand-nya tidak sama dengan 0. 1 jika nilai operan-nya sama dengan 0. hasilnya bertipe int. Ekspresi! E setara dengan (O == E). " Itu harus mencakup setiap kompiler yang pernah mengklaim mendukung standar C. Kompiler tentu saja dapat secara hukum mengabaikan aturan ini dalam kasus di mana tidak masalah untuk perilaku yang dapat diamati (seperti if(!value)), tetapi pengecualian itu tidak berlaku dalam kasus khusus ini.
user694733
48
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:
typedefintbool;#definetrue1#definefalse0
Ini tidak-tidak, karena pembaca biasa - yang memang belajar C dalam 19 tahun itu - akan mengharapkan yang boolmengacu pada tipe data aktualbool dan akan berperilaku sama, tetapi tidak! Sebagai contoh
double a =...;bool b = a;
Dengan C99 bool/ _Bool, bakan diatur ke falseiffa 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
typedefenumbool{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:
jenis intdan nilai 0dan1 apa adanya ; dan hati-hati lakukan konversi domain dari nilai-nilai lain ke ini dengan negasi ganda!!
atau jika Anda bersikeras Anda tidak ingat bahwa 0 adalah falsy dan non-nol Truish, setidaknya menggunakan huruf sehingga mereka tidak bingung dengan konsep C99: BOOL, TRUEdan FALSE!
Apa bagian dari Standar C yang akan membatasi objek tipe enumerasi untuk memegang nilai-nilai yang tercantum secara eksplisit di dalamnya? Jika nilai terbesar untuk konstanta enumerasi kurang dari UCHAR_MAX atau USHRT_MAX, suatu implementasi dapat menggunakan tipe yang lebih kecil dari intatau unsigned intuntuk menahan enumerasi, tetapi saya tidak tahu apa-apa dalam Standar yang akan menyebabkan enumerasi berperilaku sebagai selain integer Tipe.
@ technosaurus Mengambil pendekatan ini tidak menjamin! false == true karena! false dapat berupa angka yang bukan nol. Sebuah solusi sederhana untuk secara eksplisit menetapkan true to! False.
Andrew
3
@Andrew Itu tidak benar. !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`.
Jeremy West
14
C memiliki tipe boolean: bool (setidaknya selama 10 (!) Tahun terakhir)
Sertakan stdbool.h dan true / false akan berfungsi seperti yang diharapkan.
10 tahun dalam standar, tetapi tidak 10 tahun dalam kompiler! Kompilasi C MSVC ++ tidak mendukung C99 sama sekali selain mengizinkan // komentar, dan tidak mungkin melakukannya. _Bool juga didefinisikan dalam C99 sebagai tipe bawaan, sedangkan bool adalah typedef pada header <stdbool.h>.
Clifford
5
@Clifford 4 tahun berlalu sejak komentar Anda ... tidak ada yang berubah. MSVC adalah kompiler C ++ dan saya percaya MS telah mengatakan bahwa mereka tidak benar-benar tertarik untuk mendukung semua fitur C baru (C99 & C11). Tapi saya tidak bisa menganggap bahwa MSVC tidak mendukung fitur C baru sebagai alasan (terutama ketika Anda mengatakannya terhadap 10 tahun pada jawaban). 10 tahun adalah waktu yang sangat lama di dunia pemrograman. Setiap kompiler yang layak harus memiliki dukungan untuknya dalam waktu kurang dari 10 tahun jika vendor dimaksudkan untuk mendukungnya.
PP
2
@ RajaIndian: Saya tidak yakin mengapa Anda mengarahkan komentar Anda kepada saya atau bahkan merasa perlu berkomentar sama sekali. Saya hanya menyatakan situasi yang ada pada saat penulisan. Saya tidak mendukung situasi itu, hanya menunjukkan bahwa "jawaban" mungkin tidak berlaku dalam semua keadaan.
Clifford
@Clifford: Secara ketat, standar 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.
Jonathan Leffler
2
VS2015 dan yang lebih baru (& mungkin sebelumnya, sampai titik tertentu) tidak memiliki masalah dengan boolmelalui di <stdbool.h>bawah kompilasi C. Itu memutuskan untuk _Bool.
11
Apa pun yang bukan nol dievaluasi benar dalam operasi boolean, jadi Anda bisa saja
tetapi gunakan dengan hati-hati: karena hasil yang sebenarnya bisa berupa nilai bukan nol, tes jika (t == BENAR) {...} dan jika (t), yang setara dalam bahasa lain, tidak setara dalam C .
Fortega
1
Anda benar, tetapi itu juga berlaku di C ++ yang memang memiliki tipe bool, bukan? Selama debugging saya telah melihat variabel bool dengan nilai-nilai 5837834939 ...
ggambett
1
Dalam C ++, tes if (t == true) sama dengan tes if (t), karena C ++ melakukan beberapa konversi (semua yang bukan 0 atau nilai null pointer dikonversi menjadi true)
Fortega
6
Yang harus Anda asumsikan tentang nilai sebenarnya boolean adalah bahwa itu bukan nol. Jadi kode seperti jika (b) aman sementara jika (b == BENAR) tidak; yang terakhir adalah praktik buruk (dan tidak ada gunanya).
Clifford
5
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 .
Nilai yang diterima untuk 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 .
JANGAN, tapi ya, Anda bisa mendefinisikan ulang booltruedanfalse tetapi tentu saja itu bukan ide yang baik. Kemampuan ini dianggap usang dan akan dihapus di masa depan.
Menetapkan jenis skalar (tipe aritmatika dan tipe penunjuk) ke _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.
Juga di C biasanya int, dan dapat menyebabkan hilangnya peringatan presisi dengan kode lain yang menggunakan int ..
Thomas Bonini
Kecuali jika Anda mengoptimalkan ruang secara manual, selalu lebih baik menggunakan ukuran kata normal perangkat keras (misalnya: biasanya int), karena pada beberapa arsitektur Anda mendapatkan hasil kinerja yang signifikan karena harus membongkar / menutupi pemeriksaan pada variabel-variabel ini.
Kingsley
2
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;
TIDAK makro harus dilindungi oleh kurung di sekitar 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.
Jawaban:
Dari yang terbaik menjadi lebih buruk:
Opsi 1 (C99)
pilihan 2
Opsi 3
Opsi 4
Penjelasan
Jika Anda ragu-ragu, lanjutkan dengan # 1!
sumber
<stdbool.h>
bool
kompiler yang dipilih mungkin lebih cocok untuk tujuan yang diinginkan dari nilai boolean daripada menggunakanint
(yaitu kompiler dapat memilih untuk mengimplementasikan yangbool
berbeda dari padaint
). Mungkin juga menghasilkan pengecekan tipe yang lebih ketat pada waktu kompilasi, jika Anda beruntung.int
untukbool
? Itu sia-sia. Gunakanunsigned char
. Atau menggunakan C builtin_Bool
.Beberapa pemikiran tentang boolean di C:
Saya cukup tua sehingga saya hanya menggunakan
int
s 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
Ini selalu bisa diganti dengan yang lebih jelas
Perhatikan bahwa ini sebenarnya dapat secara wajar dan dimengerti dibaca dengan keras.
Beri nama positif variabel boolean Anda, yaitu
full
sebagai gantinotfull
. Yang terakhir mengarah ke kode yang sulit dibaca dengan mudah. Membandingkandengan
Kedua mantan pasangan membaca secara alami, sementara
!notfull
canggung 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
Dalam tubuh fungsi, sangat jelas apa artinya argumen karena memiliki nama yang nyaman, dan mudah-mudahan bermakna. Tapi, situs panggilan terlihat seperti
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
atau
Dalam kedua kasus, situs panggilan sekarang terlihat seperti
dimana pembaca setidaknya memiliki kesempatan untuk memahami tanpa mengeruk definisi
foo
.sumber
a == b
berhasil?a
danb
menghitung dari nol, saya akan merekomendasikana > 0 == b > 0
. Jika Anda bersikeras untuk mengambil keuntungan dari kebenaran nilai bukan nol yang sewenang-wenang,!!var
menghasilkan nilai boolean 0/1 yang setara denganvar
, sehingga Anda bisa menulis!!a == !!b
, meskipun beberapa pembaca akan menganggapnya membingungkan.!a == !b
juga 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 .
sumber
Ini adalah versi yang saya gunakan:
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:
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:
untuk menghindari tabrakan nama dengan skema lain yang mendefinisikan
true
danfalse
. Namun konsepnya tetap sama.[EDIT] Untuk menampilkan konversi integer ke boolean:
Yang pertama (paling kanan)! mengkonversi bilangan nol ke nol, kemudian bilangan bulat kedua (paling kiri)! mengkonversi 0 ke a
myfalse
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,
sumber
true
,false
danbool
disorot di sebagian besar IDE karena mereka adalah nilai enum dan typedef, sebagai lawan dari#defines
, yang jarang disorot oleh sintaks.gcc -ansi -pedantic -Wall
tidak memberikan peringatan, jadi saya percayagcc
; Jika ini berhasil bahkan untukc89
itu harus bekerjac99
juga.!
hanya dapat mengembalikan nilai0
dan1
, jaditrue = !false
akan selalu memberikan nilai 1. Metode ini tidak memberikan keamanan ekstratypedef 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:
http://en.wikipedia.org/wiki/Boolean_data_type
sumber
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 gunakantrue
,false
danbool
. Atau jangan memasukkannya, dan gunakan_Bool
,1
dan0
sebagai gantinya.Ada berbagai praktik berbahaya yang dipromosikan dalam jawaban lain untuk utas ini. Saya akan mengatasinya:
Ini tidak-tidak, karena pembaca biasa - yang memang belajar C dalam 19 tahun itu - akan mengharapkan yang
bool
mengacu pada tipe data aktualbool
dan akan berperilaku sama, tetapi tidak! Sebagai contohDengan C99
bool
/_Bool
,b
akan diatur kefalse
iffa
adalah nol, dantrue
sebaliknya. C11 6.3.1.2p1Dengan
typedef
di tempat,double
akan dipaksa keint
- jika nilai ganda tidak dalam kisaranint
, perilaku tidak terdefinisi .Secara alami hal yang sama berlaku untuk if
true
danfalse
dinyatakan dalamenum
.Apa yang lebih berbahaya adalah menyatakan
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:
int
dan nilai0
dan1
apa adanya ; dan hati-hati lakukan konversi domain dari nilai-nilai lain ke ini dengan negasi ganda!!
BOOL
,TRUE
danFALSE
!sumber
int
atauunsigned int
untuk menahan enumerasi, tetapi saya tidak tahu apa-apa dalam Standar yang akan menyebabkan enumerasi berperilaku sebagai selain integer Tipe.sumber
!0 = 1
oleh standar C, dan!a = 0
untuk nilai bukan nol daria
. Masalahnya adalah bahwa setiap non-nol dianggap benar. Jadi jikaa
danb
keduanya "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.
sumber
bool
harus makro yang diperluas_Bool
. Perbedaannya penting karena Anda bisa#undef
makro (dan itu diizinkan, setidaknya sebagai ukuran transisi), tetapi Anda tidakuntypedef
bisa mengetik. Itu tidak mengubah dorongan utama dari komentar pertama Anda.bool
melalui di<stdbool.h>
bawah kompilasi C. Itu memutuskan untuk_Bool
.Apa pun yang bukan nol dievaluasi benar dalam operasi boolean, jadi Anda bisa saja
dan gunakan konstanta.
sumber
Hanya pelengkap jawaban lain dan klarifikasi, jika Anda diizinkan menggunakan C99.
Beberapa preferensi saya:
_Bool
ataubool
? Keduanya baik-baik saja, tetapibool
terlihat lebih baik daripada kata kunci_Bool
.bool
dan_Bool
adalah:false
atautrue
. Menetapkan0
atau1
bukannyafalse
atautrue
valid, tetapi lebih sulit untuk membaca dan memahami aliran logika.Beberapa info dari standar:
_Bool
TIDAKunsigned int
, tetapi merupakan bagian dari grup tipe integer yang tidak ditandai . Cukup besar untuk menampung nilai0
atau1
.bool
true
danfalse
tetapi tentu saja itu bukan ide yang baik. Kemampuan ini dianggap usang dan akan dihapus di masa depan._Bool
ataubool
, jika nilai skalar sama0
atau membandingkannya dengan0
itu0
, jika tidak hasilnya adalah1
:_Bool x = 9;
9
dikonversi menjadi1
ketika ditugaskanx
._Bool
adalah 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 tipechar
yang memiliki 8 bit tersedia.sumber
Ini dia:
sumber
Anda dapat menggunakan arang, atau wadah nomor kecil lainnya untuknya.
Kode semu
sumber
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:
sumber
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:
Beberapa kompiler akan menghasilkan peringatan tentang konversi bool int =>. Terkadang orang menghindari ini dengan melakukan:
untuk memaksa ekspresi menjadi bool C ++. Tetapi jika Anda #menentukan BENAR! SALAH, Anda berakhir dengan:
yang akhirnya melakukan perbandingan int-to-bool yang dapat memicu peringatan itu.
sumber
Jika Anda menggunakan C99 maka Anda dapat menggunakan
_Bool
jenisnya. Tidak#include
perlu. Anda perlu memperlakukannya seperti integer, meskipun, di mana1
adalahtrue
dan0
adalahfalse
.Anda kemudian dapat mendefinisikan
TRUE
danFALSE
.sumber
#include <stdbool.h>
dan penggunaanbool
,true
danfalse
seperti standar ingin Anda.Saat ini C99 mendukung tipe boolean tetapi Anda harus melakukannya
#include <stdbool.h>
.Contoh:
Keluaran:
sumber
Inilah yang saya gunakan:
_Bool
adalah tipe bawaan C. Ini dimaksudkan untuk nilai boolean.sumber
Anda cukup menggunakan
#define
arahan sebagai berikut:Dan gunakan sebagai berikut:
dan seterusnya
sumber
arg
dan ekspresi secara keseluruhan:#define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE)
. Namun, akan lebih baik untuk menguji kepalsuan (itu akan memberikan jawaban yang benar bahkan jikaarg
itu 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.