C'de tanımları gördüm
#define TRUE (1==1)
#define FALSE (!TRUE)
Bu gerekli mi? TRUE değerini 1 ve FALSE değerini 0 olarak tanımlamanın avantajı nedir?
C'de tanımları gördüm
#define TRUE (1==1)
#define FALSE (!TRUE)
Bu gerekli mi? TRUE değerini 1 ve FALSE değerini 0 olarak tanımlamanın avantajı nedir?
Yanıtlar:
Bu yaklaşım , derleyici destekliyorsa gerçek boolean
türü kullanır (ve çözümlemesi true
ve için false
). (özellikle C ++)
Ancak, C ++ (aracılığıyla kullanımda olup olmadığını kontrol etmek daha iyi olurdu __cplusplus
makro) ve aslında kullanmak true
ve false
.
Bir Cı derleyici, bu eşdeğerdir 0
ve 1
.
(parantezlerin kaldırılmasının işlem sırası nedeniyle kesileceğini unutmayın)
1==1
bir int
. (bkz. stackoverflow.com/questions/7687403/… .)
boolean
türü ile?
true
veya false
.
#define TRUE true
ve #define FALSE false
ne zaman __cplusplus
tanımlanır.
Cevap taşınabilirliktir. Sayısal değerleri önemlidir TRUE
ve FALSE
önemli değildir. Ne olduğunu önemlidir gibi bir deyimi o if (1 < 2)
kadar değerlendirir if (TRUE)
ve benzeri bir açıklamada if (1 > 2)
için değerlendirir if (FALSE)
.
C olarak kabul (1 < 2)
edilir 1
ve (1 > 2)
değerlendirilir 0
, diğerlerinin söylediği gibi, derleyici açısından pratik bir fark yoktur. Ancak derleyicinin kendi kurallarına göre tanımlamasına TRUE
ve FALSE
kendi kurallarına göre, anlamlarını programcılara açık hale getiriyorsunuz ve programınızdaki ve diğer kütüphanelerinizde tutarlılığı garanti ediyorsunuz (diğer kütüphanenin C standartlarına uyduğu varsayılırsa ... şaşıracaksınız).
Bazı Geçmişi
Bazı BASICler tanımlandığı FALSE
şekilde 0
ve TRUE
olduğu gibi -1
. Birçok modern dil gibi , sıfır olmayan herhangi bir değeri olarak yorumladılarTRUE
, ancak doğru olan boole ifadelerini değerlendirdiler-1
. Onların NOT
o bu şekilde yapmaya verimli olduğu için operasyon, 1 ekleme ve işareti saygısız tarafından hayata geçirildi. Böylece 'NOT x' oldu -(x+1)
. Bunun bir yan etkisi, benzeri bir değerin 5
değerlendirildiği TRUE
, ancak NOT 5
değerlendirildiği -6
, ki bu da TRUE
! Bu tür bir hata bulmak eğlenceli değil.
İyi Uygulamalar
Verilen fiilen sıfır olarak yorumlanır olduğunu kurallarını FALSE
ve herhangi olarak sıfır olmayan bir değer yorumlanır TRUE
sen gerektiğini boole görünümlü ifadeleri karşılaştırmak asla TRUE
yaFALSE
. Örnekler:
if (thisValue == FALSE) // Don't do this!
if (thatValue == TRUE) // Or this!
if (otherValue != TRUE) // Whatever you do, don't do this!
Neden? Çünkü birçok programcı int
s'yi tedavi etme kısayolunu kullanır bool
. Aynı değiller, ancak derleyiciler genellikle buna izin verir. Yani, örneğin, yazmak tamamen yasal
if (strcmp(yourString, myString) == TRUE) // Wrong!!!
Bu meşru görünüyor ve derleyici bunu mutlu bir şekilde kabul edecek, ancak muhtemelen istediğinizi yapmaz. Yani en yüzünden dönüş değeri strcmp()
DİR
0 ise yourString == myString
<0 ise yourString < myString
> 0 iseyourString > myString
Yani yukarıdaki çizgi TRUE
sadece ne zaman geri döner yourString > myString
.
Bunu yapmanın doğru yolu ya
// Valid, but still treats int as bool.
if (strcmp(yourString, myString))
veya
// Better: lingustically clear, compiler will optimize.
if (strcmp(yourString, myString) != 0)
Benzer şekilde:
if (someBoolValue == FALSE) // Redundant.
if (!someBoolValue) // Better.
return (x > 0) ? TRUE : FALSE; // You're fired.
return (x > 0); // Simpler, clearer, correct.
if (ptr == NULL) // Perfect: compares pointers.
if (!ptr) // Sleazy, but short and valid.
if (ptr == FALSE) // Whatisthisidonteven.
Genellikle bu "kötü örneklerin" bazılarını üretim kodunda bulacaksınız ve birçok deneyimli programcı onlar tarafından yemin ediyor: çalışıyorlar, bazıları (bilgiçlik?) Doğru alternatiflerinden daha kısadır ve deyimler neredeyse evrensel olarak tanınır. Ancak şunu düşünün: "doğru" sürümler daha az verimli değildir, taşınabilir olmaları garanti edilir, en katı linterleri bile geçer ve hatta yeni programcılar bile bunları anlar.
Buna değmez mi?
(1==1)
daha taşınabilir değil 1
. Derleyicinin kendi kuralları, eşitlik ve ilişkisel işleçlerin anlambilimi konusunda açık ve net olan C dilinin kurallarıdır. Bir derleyicinin bu şeyleri yanlış yaptığını hiç görmedim.
strcmp
0'dan küçük, eşit veya 0'dan büyük olduğu bilinmektedir. -1, 0 veya 1 olduğu garanti edilmez ve wild'da uygulama hızını kazanmak için bu değerleri döndürmeyen platformlar vardır. Eğer strcmp(a, b) == TRUE
öyleyse, a > b
ancak ters ima tutunmayabilir.
(1==1)
ve 1
her ikisi de int
1 değerine sahip sabit tip ifadelerdir. Anlamsal olarak aynıdırlar. Sanırım bunu bilmeyen okuyuculara hitap eden bir kod yazabilirsiniz, ama nerede bitiyor?
(1 == 1)
Hüner tanımlamak için yararlıdır TRUE
C ++ şeffaf bir şekilde, henüz C daha iyi yazarak sağlar. "Temiz C" (C veya C ++ olarak derlenen) bir lehçede yazıyorsanız veya C veya C ++ programcıları tarafından kullanılabilecek API başlık dosyaları yazıyorsanız, aynı kod C veya C ++ olarak yorumlanabilir.
Cı çeviri birimleri olarak, 1 == 1
tam olarak aynı anlamlara sahiptir 1
; ile 1 == 0
aynı anlama sahiptir 0
. Ancak, C ++ çeviri birimlerinde 1 == 1
türü vardır bool
. Yani TRUE
bu şekilde tanımlanan makro C ++ 'a daha iyi entegre olur.
Nasıl daha iyi entegre edileceğinin bir örneği, örneğin işlev foo
için int
ve için aşırı yük varsa bool
, o foo(TRUE)
zaman bool
aşırı yükü seçecektir . Eğer TRUE
sadece olarak tanımlanır 1
, o zaman C ++ içinde güzel çalışmayacaktır. aşırı yük foo(TRUE)
isteyecek int
.
Tabii ki, C99 tanıtıldı bool
, true
ve false
bu başlık dosyalarında kullanılabilen C99 ile ve C ile çalışmak olduğunu
Ancak:
TRUE
ile FALSE
olduğu gibi (0==0)
ve (1==0)
C99 eskidir.Eğer bir karma C ve C ++ projede çalışıyoruz ve C99 istemiyorsanız, alt durum tanımlamak true
, false
ve bool
bunun yerine.
#ifndef __cplusplus
typedef int bool;
#define true (0==0)
#define false (!true)
#endif
Bununla birlikte, 0==0
hile, bazı programcılar tarafından hiçbir zaman C ++ ile birlikte çalışması amaçlanmayan kodda bile kullanıldı (?). Bu hiçbir şey satın almaz ve programcının C'de boolelerin nasıl çalıştığını yanlış anladığını gösterir.
C ++ açıklaması net değilse, bir test programı aşağıdadır:
#include <cstdio>
void foo(bool x)
{
std::puts("bool");
}
void foo(int x)
{
std::puts("int");
}
int main()
{
foo(1 == 1);
foo(1);
return 0;
}
Çıktı:
bool
int
Aşırı C ve C ++ programlama ile ilgili aşırı yüklenmiş C ++ fonksiyonlarının yorumlarından gelen soruya gelince. Bunlar sadece bir tip farkı göstermektedir. C ++ olarak derlendiğinde bir true
sabitin olmasını istemenin geçerli bir nedeni bool
temiz teşhis içindir. En yüksek uyarı düzeylerinde, bir C ++ derleyicisi bool
parametre olarak bir tamsayıyı iletirsek, dönüşüm konusunda bizi uyarabilir . Temiz C'de yazmanın bir nedeni sadece kodumuzun daha taşınabilir olması değildir (çünkü sadece C derleyicileri değil, C ++ derleyicileri tarafından da anlaşılır), ancak C ++ derleyicilerinin tanılama görüşlerinden de yararlanabiliriz.
TRUE
C ++ altında farklılık göstereceği açık değildir .
#ifdef __cplusplus
, niyetinizi çok daha açık bir şekilde ifade etmek için kullanabilirsiniz .
bool
ve int
örtük birbirlerine dönüştürülebilir (ve de çünkü çok önemli değil pratikte do C aslında "aynı" , tırnak dikkat olsa da) ve ikisi arasında gerçekten saptamanız gereken birçok durum yok . "fazla değil" muhtemelen çok ağırdı, "şablonlar ve aşırı yükleme kullanan kodlara kıyasla çok daha az" belki daha iyi olurdu.
#define TRUE (1==1)
#define FALSE (!TRUE)
eşittir
#define TRUE 1
#define FALSE 0
C cinsinden
İlişkisel işleçlerin sonucu 0
veya 1
. 1==1
için değerlendirilmesi 1
ve değerlendirilmesi için !(1==1)
garanti edilir 0
.
İlk formu kullanmak için kesinlikle hiçbir neden yoktur. Bununla birlikte, birinci formun hemen hemen tüm derleyicilerde olduğu gibi, sabit bir ifadenin çalışma zamanında değil, derleme zamanında değerlendirildiğini unutmayın. Bu kurala göre izin verilir:
(C99, 6.6p2) "Sabit bir ifade, çalışma sırasında değil çeviri sırasında değerlendirilebilir ve buna göre, bir sabitin olabileceği herhangi bir yerde kullanılabilir."
PC-Lint, için hazır bilgi TRUE
ve FALSE
makro kullanmazsanız bir ileti (506, sabit değer boole) bile gönderir :
C için,
TRUE
olarak tanımlanmalıdır1
. Bununla birlikte, diğer diller 1 dışındaki miktarları kullanır, bu nedenle bazı programcılar!0
bunu güvenli oynadığını düşünür.
Ayrıca C99'da, stdbool.h
boolean makroları true
ve false
doğrudan değişmez değerleri tanımları :
#define true 1
#define false 0
1==1
1
if(foo == true)
, sadece kötü uygulamadan düz arabayı alacak olan formun kodu için önemlidir .
(x == TRUE)
, bundan farklı bir gerçek değerine sahip olabilir x
.
C ++ (daha önce de belirtilmiş) dışında, bir diğer avantaj da statik analiz araçlarıdır. Derleyici herhangi bir verimsizliği ortadan kaldıracaktır, ancak statik bir analizör karşılaştırma sonuçlarını ve diğer tamsayı tiplerini ayırt etmek için kendi soyut tiplerini kullanabilir, bu nedenle dolaylı olarak TRUE'nun bir karşılaştırmanın sonucu olması gerektiğini ve uyumlu olduğu varsayılmaması gerektiğini bilir. bir tamsayı ile.
Açıkçası C uyumlularsa olduğunu söylüyor, ancak yardım vurgulamak hatalar için bu özellik kasıtlı kullanımını yasaklayan tercih edebilir - örneğin, birileri karıştırmayın olabilir nerede &
ve &&
ya onların operatör öncelik bungled ettik.
if (boolean_var == TRUE)
genişleme yoluyla aptalca kod yakalayabilir . if (boolean_var == (1 == 1))
(1 == 1)
if (<*> == <boolean_expr>)
Pratik fark yok. 0
olarak değerlendirilir false
ve 1
olarak değerlendirilir true
. Bir kullanmak gerçeği boolean ifadesini ( 1 == 1
) ya da 1
tanımlamak için, true
herhangi bir fark yaratmaz. İkisi de değerlendirilir int
.
Uyarı C standart kütüphanesi Boolean tanımlamak için özel bir başlık sağladığını: stdbool.h
.
true
olarak değerlendirilir 1
ve false
olarak değerlendirilir 0
. C yerli boole türlerini bilmiyor, sadece ints.
int
değer içeren sonuçlar verir . C (gerçek boolean türü var bir makro ile, tanımlanmış , ama bu sadece yoktu, C99 ile eklendi değil yeni türünü kullanmak için operatörlerin semantiğini değiştirin.0
1
_Bool
bool
<stdbool.h>
_Bool
ve <stdbool.h>
vardır #define bool _Bool
.
1 == 1
olarak değerlendirilme konusunda haklısınız int
. Düzenlenen.
DOĞRU'nun eşit olduğu kesin değeri bilmiyoruz ve derleyicilerin kendi tanımları olabilir. Privode yaptığınız şey derleyicinin dahili tanımını kullanmaktır. İyi programlama alışkanlıklarınız varsa bu her zaman gerekli değildir, ancak bazı kötü kodlama stilleriyle ilgili sorunları önleyebilir, örneğin:
if ((a> b) == DOĞRU)
TRUE değerini manüel olarak 1 olarak tanımlarsanız bu bir felaket olabilirken, TRUE iç değeri başka bir değerdir.
>
operatör daima true için 1, false için 0 verir. Herhangi bir C derleyicisinin bunu yanlış anlama olasılığı yoktur. Eşitlik karşılaştırmaları TRUE
ve FALSE
zayıf üslup; yukarıdakiler daha net olarak yazılmıştır if (a > b)
. Ancak farklı C derleyicilerinin gerçeği ve yanlışları farklı şekilde ele alabileceği fikri yanlıştır.
Tipik olarak C Programlama Dili'nde 1, true olarak ve 0, false olarak tanımlanır. Bu nedenle aşağıdakileri neden sıklıkla görüyorsunuz:
#define TRUE 1
#define FALSE 0
Ancak, koşullu bir ifadede 0'a eşit olmayan herhangi bir sayı doğru olarak değerlendirilir. Bu nedenle aşağıdakileri kullanarak:
#define TRUE (1==1)
#define FALSE (!TRUE)
Yanlış olanı yanlış olana eşit yaparak onu güvenli bir şekilde oynamaya çalıştığınızı açıkça gösterebilirsiniz.
#define TRUE (’/’/’/’)
:;#define FALSE (’-’-’-’)
( coding-guidelines.com/cbook/cbook1_1.pdf sayfa 871 adresinden alınmıştır )