C'nin yerleşik boole türü yoktur. Onları C'de kullanmanın en iyi yolu nedir?
C'nin yerleşik boole türü yoktur. Onları C'de kullanmanın en iyi yolu nedir?
Yanıtlar:
En iyiden kötüye:
Seçenek 1 (C99)
#include <stdbool.h>
seçenek 2
typedef enum { false, true } bool;
Seçenek 3
typedef int bool;
enum { false, true };
Seçenek 4
typedef int bool;
#define true 1
#define false 0
Kararsızsanız # 1 ile devam edin!
<stdbool.h>
bool
derleyici seçer bir kullanan daha Boole değer hedeflenen amaca daha uygun olabilir int
(bir uygulamayı tercih edilebilir, yani derleyici bool
farklı bir daha int
). Ayrıca, eğer şanslıysanız, derleme zamanında daha katı tip kontrolüne neden olabilir.
int
için bool
? Bu savurgan. Kullanın unsigned char
. Ya da C'nin yerleşikini kullanın _Bool
.
C'deki booleans hakkında birkaç düşünce:
Ben int
herhangi bir typedefs veya özel tanımlar veya doğru / yanlış değerleri için numaralandırma olmadan boolean türüm olarak yalnızca düz s kullanacak kadar yaşlıyım. Boole sabitleriyle hiçbir zaman karşılaştırma yapma konusunda aşağıdaki önerilerimi uygularsanız, yine de bayrakları başlatmak için yalnızca 0/1 kullanmanız gerekir. Bununla birlikte, böyle bir yaklaşım bu modern zamanlarda çok gerici olarak görülebilir. Bu durumda, <stdbool.h>
en azından standardize olma avantajına sahip olduğu için kesinlikle kullanılmalıdır .
Boole sabitleri ne denirse adlandırın, bunları yalnızca başlatma için kullanın. Asla böyle bir şey yazmayın
if (ready == TRUE) ...
while (empty == FALSE) ...
Bunlar her zaman temizleyici ile değiştirilebilir
if (ready) ...
while (!empty) ...
Bunların makul ve anlaşılır bir şekilde yüksek sesle okunabileceğini unutmayın.
Senin boolean değişkenler pozitif isimleri, yani ver full
yerine notfull
. İkincisi, kolayca okunması zor olan koda yol açar. Karşılaştırmak
if (full) ...
if (!full) ...
ile
if (!notfull) ...
if (notfull) ...
Eski çiftin her ikisi de doğal olarak okurken, !notfull
olduğu gibi okumak zor ve daha karmaşık boole ifadelerinde çok daha kötü hale geliyor.
Boole argümanlarından genellikle kaçınılmalıdır. Bu şekilde tanımlanan bir işlevi düşünün
void foo(bool option) { ... }
Fonksiyonun bünyesinde, argümanın ne anlama geldiği çok açıktır, çünkü uygun ve umarım anlamlı bir isme sahiptir. Ancak, arama siteleri
foo(TRUE);
foo(FALSE):
Burada, parametrenin her zaman işlev tanımına veya bildirimine bakmadan ne anlama geldiğini söylemek imkansızdır ve daha fazla boole parametresi eklerseniz çok daha kötü hale gelir. Ben de öneririm
typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);
veya
#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }
Her iki durumda da, çağrı sitesi artık
foo(OPT_ON);
foo(OPT_OFF);
okuyucunun tanımını taramadan en azından anlama şansı vardır foo
.
a == b
mı?
a
ve b
sıfırdan saymak, ben tavsiye ederim a > 0 == b > 0
yerine. Sıfır olmayan rasgele değerlerin doğruluğundan faydalanmakta ısrar ederseniz !!var
, boolean 0/1 değerine eşdeğerdir var
, bu nedenle yazabilirsiniz !!a == !!b
, ancak birkaç okuyucu kafa karıştırıcı bulacaktır.
!a == !b
eşitliği test etmek için de yeterlidir, sıfır olmayanlar sıfır olur ve sıfırlar bir olur.
!!a
"boolean olmayan a'yı eşdeğer doğruluk değerine dönüştür !a
" olarak okurken , "mantıksal boole değişkenini mantıksal olarak ters çevir" olarak okurdum . Özellikle, mantıksal tersinmenin istendiği belirli bir sebep ararım.
C'deki bir boolean bir tamsayıdır: false için sıfır ve true için sıfır olmayan.
Ayrıca bkz. Boolean veri türü , bölüm C, C ++, Objective-C, AWK .
İşte kullandığım sürüm:
typedef enum { false = 0, true = !false } bool;
Çünkü yanlış yalnızca bir değere sahiptir, ancak mantıksal bir doğru birçok değere sahip olabilir, ancak teknik derleyicinin yanlışın tersi için kullanacağı şekilde doğrudur.
Bu, aşağıya inecek bir şeyi kodlayan birinin sorununu halleder:
if (true == !false)
Sanırım hepimiz bunun iyi bir uygulama olmadığı konusunda hemfikiriz, ama bir defalık maliyeti için "true =! False" bu sorunu ortadan kaldırıyoruz.
[EDIT] Sonunda kullandım:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
tanımlayan diğer şemalarla isim çarpışmasını önlemek true
ve false
. Ancak konsept aynı kalır.
[EDIT] Tamsayının boole dönüştürmesini göstermek için:
mybool somebool;
int someint = 5;
somebool = !!someint;
İlk (en doğru)! sıfır olmayan tamsayıyı 0'a, sonra ikinciye (en solda) dönüştürür! 0 myfalse
değerini bir değere dönüştürür . Okuyucunun sıfır tamsayısını dönüştürmesi için bir alıştırma olarak bırakacağım.
[EDIT] Benim tarzım, varsayılan değer aynı olsa bile, belirli bir değer gerektiğinde numaralandırmada bir değerin açık ayarını kullanmaktır. Örnek: Yanlışın sıfır olması gerektiğinden false = 0,
,false,
true
, false
ve bool
vurgulanır en IDE Hadi onlar yerine enum değerler ve Typedef, çünkü #defines
nadiren sözdizimi vurgulanan vardır.
gcc -ansi -pedantic -Wall
hiçbir uyarı vermiyor , bu yüzden güveniyorum gcc
; Bu bile c89
işe c99
yarıyorsa da işe yaramalıdır.
!
yalnızca değerleri döndürebilir 0
ve 1
böylece true = !false
her zaman 1 değerini atayacaktır. Bu yöntem fazladan güvenlik sağlamaz typedef enum { false, true } bool;
.
if(!value)
) için önemli olmadığı durumlarda bu kuralı yasal olarak göz ardı edebilir , ancak bu özel durumda bu istisna geçerli değildir.
Bir C99 derleyicisi kullanıyorsanız, bool türleri için yerleşik desteğe sahiptir:
#include <stdbool.h>
int main()
{
bool b = false;
b = true;
}
Her şey sırayla. C, yani ISO / IEC 9899 19 yıldır boole tipine sahip . Bu, bu soruyu ziyaret ederken amatör / akademik / profesyonel bölümlerle birlikte C programlama kariyerinin beklenen süresinden çok daha uzun bir süre . Benimki bunu belki 1-2 yıl geçiyor. Bu, ortalama bir okuyucunun C hakkında hiçbir şey öğrenmediği sırada C'nin aslında boole veri türüne sahip olduğu anlamına gelir .
Veri türü #include <stdbool.h>
ve true
, false
ve için bool
. Ya da, ve kullanımını içermez _Bool
, 1
ve 0
bunun yerine.
Bu konuya verilen diğer cevaplarda teşvik edilen çeşitli tehlikeli uygulamalar vardır . Onlara hitap edeceğim:
typedef int bool;
#define true 1
#define false 0
Bu hayır-hayır, çünkü 19 yıl içinde C öğrenen sıradan bir okuyucu bool
, bunun gerçek bool
veri türüne atıfta bulunmasını ve benzer şekilde davranmasını beklerdi , ama öyle değil! Örneğin
double a = ...;
bool b = a;
C99 ile bool
/ _Bool
, b
atanabilir false
IFF a
sıfır ve oldu true
aksi. C11 6.3.1.2p1
- Herhangi bir skaler değer dönüştürüldüğünde
_Bool
, değer 0 ile karşılaştırılırsa sonuç 0 olur; aksi takdirde sonuç 1 olur. 59)Dipnotlar
59) NaN'ler 0'a eşit değildir ve bu nedenle 1'e dönüşür.
İle typedef
yerinde, double
bir coerced olacağını int
çift değeri aralığında değilse - int
, davranış tanımlanmamış .
Doğal olarak aynı ise uygulanır true
ve false
bir beyan edilmiştir enum
.
Ne olduğunu bile daha tehlikeli ilan edilir
typedef enum bool {
false, true
} bool;
çünkü şimdi 1 ve 0 dışındaki tüm değerler geçersizdir ve böyle bir değerin bu türdeki bir değişkene atanması gerektiğinden , davranış tamamen tanımsız olur .
Bu nedenle IFF bazı açıklanamaz nedenle C99 kullanamaz, boolean değişkenler için kullanmalısınız:
int
ve değerler 0
ve 1
olduğu gibi ; ve diğer herhangi bir değerden bunlara etki alanı dönüşümlerini dikkatlice çift olumsuzlama ile yapın!!
BOOL
, TRUE
ve FALSE
!int
veya unsigned int
numaralandırmanın tamsayıdan başka bir şey olarak davranmasına neden olacak hiçbir şey bilmiyorum yazın.
typedef enum {
false = 0,
true
} t_bool;
!0 = 1
C standardına göre ve !a = 0
sıfır olmayan herhangi bir değeri için a
. Sorun, sıfır olmayan herhangi bir şeyin doğru olarak kabul edilmesidir. Yani a
ve eğer b
her ikisi de "doğru" ise, mutlaka "a == b" söz konusu değildir.
C'nin bir boole türü vardır: bool (en azından son 10 (!) Yıl için)
Dahil stdbool.h ve true / false beklendiği gibi çalışacaktır.
bool
genişleyen bir makro olması gerekir _Bool
. Fark önemlidir çünkü #undef
bir makro yapabilirsiniz (ve buna izin verilir, en azından geçici bir önlem olarak), ancak untypedef
typedef'i kullanamazsınız . Yine de, ilk yorumunuzun ana itişini değiştirmez.
Boole olmayan işlemlerde sıfır olmayan her şey true olarak değerlendirilir, böylece
#define TRUE 1
#define FALSE 0
ve sabitleri kullanın.
C99 kullanmanıza izin verilirse, diğer cevapları ve bazı açıklamaları tamamlamanız yeterlidir.
+-------+----------------+-------------------------+--------------------+
| 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 |
+-------+----------------+-------------------------+--------------------+
Bazı tercihlerim:
_Bool
veya bool
? Her ikisi de iyi, ancak bool
anahtar kelimeden daha iyi görünüyor _Bool
.bool
ve _Bool
şunlardır: false
ya true
. Atama 0
veya 1
yerine false
veya true
geçerli, ancak okumak ve mantık akışını anlamak zordur.Standarttan bazı bilgiler:
_Bool
DEĞİL unsigned int
, ancak grup işaretsiz tamsayı türlerinin bir parçasıdır . Değerleri tutacak kadar büyük 0
veya 1
.bool
true
ve false
ancak iyi bir fikir değildir. Bu yetenek eskimiş kabul edilir ve gelecekte kaldırılacaktır._Bool
bool
0
0
0
1
_Bool x = 9;
9
1
x
_Bool
1 byte (8 bit), genellikle programcı diğer bitleri kullanmaya denemek için cazip olduğunu, ancak yalnızca verildiği garanti yalnızca bir bit olduğu için tavsiye edilmez değil, tipi gibi veri depolamak için kullanılmasıdır char
8 var bit kullanılabilir.Bunun için bir karakter veya başka bir küçük sayı kabı kullanabilirsiniz.
Sözde kod
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
int
) kullanmak her zaman daha iyidir , çünkü bazı mimarilerde bu değişkenler üzerindeki kontrolleri açmak / maskelemek zorunda kalmaktan önemli bir performans artışı elde edersiniz.
_Bool kullanabilirsiniz, ancak dönüş değeri bir tamsayı olmalıdır (true için 1, false için 0). Dedi Ancak, ++ dahildir ve C gibi kullanım bool önerilir bu yanıttan gelen daniweb forumda yanı sıra bu cevap bu diğer stackoverflow sorudan,:
_Bool: C99'un boole türü. _Bool'u doğrudan kullanmak yalnızca bool, true veya false için makroları tanımlayan eski kodu koruyorsanız önerilir. Aksi takdirde, bu makrolar başlıkta standartlaştırılır. Bu üstbilgiyi ekleyin ve boole C ++ 'da yaptığınız gibi kullanabilirsiniz.
Koşullu ifadeler sıfırdan farklıysa doğru kabul edilir, ancak C standardı mantıksal işleçlerin kendilerinin 0 veya 1 döndürmesini gerektirir.
@Tom: #define DOĞRU! YANLIŞ kötü ve tamamen anlamsız. Başlık dosyası derlenmiş C ++ koduna girerse sorunlara yol açabilir:
void foo(bool flag);
...
int flag = TRUE;
foo(flag);
Bazı derleyiciler int => bool dönüşümü hakkında bir uyarı oluşturur. Bazen insanlar bunu yaparak kaçınırlar:
foo(flag == TRUE);
ifadeyi bir C ++ boole olmaya zorlamak. Ama eğer DOĞRU! YANLIŞ # tanımlıyorsanız, sonuçta:
foo(flag == !0);
bu da uyarıyı yine de tetikleyebilecek bir bool-içi karşılaştırması yapar.
C99 kullanıyorsanız, _Bool
türü kullanabilirsiniz . Hiçbir #include
s gerekli. Nerede olsa Sen, bir tamsayı gibi davranın gerekiyor 1
ise true
ve 0
olduğufalse
.
Ardından TRUE
ve öğelerini tanımlayabilirsiniz 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>
ve kullanabilirsiniz bool
, true
ve false
standart gibi istiyor.
Ne kullanıyorum:
enum {false, true};
typedef _Bool bool;
_Bool
C'de yerleşik bir tiptir. Boole değerleri için tasarlanmıştır.
#define
Direktifi aşağıdaki gibi kullanabilirsiniz :
#define TRUE 1
#define FALSE 0
#define NOT(arg) (arg == TRUE)? FALSE : TRUE
typedef int bool;
Ve aşağıdaki gibi kullanın:
bool isVisible = FALSE;
bool isWorking = TRUE;
isVisible = NOT(isVisible);
ve bunun gibi
arg
ve bir bütün olarak ifade: #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE)
. Bununla birlikte, yanlışlığı test etmek daha iyi olacaktır arg
(0 veya 1 yerine 23 olsa bile doğru cevabı verecektir : #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)
Ancak tüm ifade #define NOT(arg) (!(arg))
elbette aynı sonucu veren azaltılabilir