bool'dan int'e dönüştürme


131

Bu dönüşüm ne kadar taşınabilir? Her iki iddianın da geçtiğinden emin olabilir miyim?

int x = 4<5;
assert(x==1);

x = 4>5;
assert(x==0);

Neden diye sorma. Bunun çirkin olduğunu biliyorum. Teşekkür ederim.


Neden ilk ifadeyi değiştirmiyorsun? Yazabilirsin assert(x!=0). Bool (doğru) taşınabilirliği int (1) 'e dönüştürse bile, "yanlış değil" iddiaları daha okunabilir bir ifadeye sahiptir.
harper

1
Neden olmasın: assert( 4 < 5);veassert(!( 4 > 5));
Martin York

4
@harper: Bir karşılaştırma ifadesinin gerekli değerini kullanmak tamamen mantıklı.
R .. GitHub BUZA YARDIM ETMEYİ DURDUR

@ R._ Soru, bool-int dönüşümü makul bir sonuç verirse, buna güvenmem. Yazar, bu gerekliliğin yerine getirildiğinden şüphe duyduğunda, okuyucu aynı sorunu yaşayabilir. Özellikle x'in değeri kontrol edilecek koşul değil, sadece bir ara sonuç olduğu için.
harper

3
(4 < 5) ? 1 : 0Bir booleanı gerçekten 0 veya 1'e dönüştürmem gerekirse muhtemelen yazardım. İyi bir derleyici muhtemelen aynı makine kodunu üretir ve bir insan okuyucu için daha nettir.
ollb

Yanıtlar:


205
int x = 4<5;

Tamamen taşınabilir. Standart uyumlu. booliçin intdönüşüm örtülü olduğunu!

C ++ Standardından §4.7 / 4 (Integral Conversion ) diyor

Kaynak türü bool ise, değer falsesıfıra ve değer truebire dönüştürülür .


C gelince, olarak bildiğim kadarıyla hiçbir yoktur boolYani (1999 öncesi) C. booliçin intdönüşüm sadece C ++ alakalı olduğunu. C, 4<5olarak değerlendirilir intdeğeri değeri, bu durumda 1, 4>5 ile sonuçlanacağından 0.

DÜZENLEME: Yorumda Jens dedi, C99'un _Booltipi var. başlık dosyasında booltanımlanan bir makrodur stdbool.h. trueve falseayrıca içinde makro tanımlanmıştır stdbool.h.

C99'dan §7.16 diyor ki,

Makro bool, _Bool'a genişler.

[..] truetamsayı sabit değin genişleyen 1, false tam sayı sabit şekilde genişler 0, [..]


3
bool1999'dan beri C'de olduğundan emin olun . Sadece "stdbool.h" başlığını kullanın ve bu dahil edilmelidir.
Jens Gustedt

1
Aslında, birkaç derleyicide kontrol ettim ve taşınabilir gibi görünüyor.
pic11

8
Ne olursa olsun C dili ve mevcudiyeti versiyonunun bool/ _Booltipi, C üretmek konusunda ilişkisel operatörler intdeğil bool. Yani C99'da bile ilişkisel operatörler hala üretiyor int.
AnT

51

Sorunuzu [C] ve [C ++] aynı anda etiketlediniz. Sonuçlar diller arasında tutarlı olacaktır ancak cevabın yapısı bu dillerin her biri için farklıdır.

C dilinde örneklerinizin hiçbir boolşekilde (C99 için de geçerlidir) hiçbir ilgisi yoktur . C dilinde ilişkisel operatörler boolsonuç üretmez . Her ikisi de 4 > 5ve değerleriyle 4 < 5tür sonuçları üreten ifadelerdir veya . Dolayısıyla, C'deki örneklerinizde yer alan herhangi bir "bool-int dönüşümü" yoktur.int01

C ++ 'da ilişkisel operatörler gerçekten boolsonuç üretir . booldeğerleri dönüştürülebilir intile, tip truedönüştürme 1ve falsedönüştürme 0. Bu, dil tarafından garanti edilmektedir.

PS C dili ayrıca özel bir boole türüne _Bool(makro takma ad bool) sahiptir ve integral dönüştürme kuralları esasen C ++ 'daki ile aynıdır. Ancak yine de bu, C'deki özel örneklerinizle ilgili değildir. Bir kez daha, C'deki ilişkisel operatörler , dil spesifikasyonunun versiyonuna bakılmaksızın her zaman sonuç üretir int( üretmez bool).


2
Doğru, K&R C'de bool yok. Sorumu C99 olarak yeniden etiketledim.
pic11

@ pic11: Hiçbir şeyi yeniden etiketlemeye gerek yoktu. Bunun K&R veya başka bir C ile hiçbir ilgisi yok bool. C99'da olsa bile , ilişkisel operatörler hala intC99'da üretiyor , değil bool. Dolayısıyla, ilgilendiğiniz konu özellikle ilişkisel operatörler ise (örneklerinizde olduğu gibi), sorunun yine de ilgisi yoktur bool.
AnT

Şimdi anladım. İlişki operatörünün sonucu örtülü olarak int'e dönüştürülebilir. Bu, C, C99 ve C ++ için geçerlidir. Yeniden hedeflendi.
pic11

3
@ pic11: Hayır, anlamıyorsun. C'de, C99 dahil, bir karşılaştırma operatörünün sonucu a intdeğil, a'dır bool. Dönüşüm olmuyor.
R .. GitHub BUZ YARDIMINI DURDUR

Bir dilin benzer davranan boolancak adresinin alınmasına izin vermeyen bir türe sahip olmasının standartlara uygun bir yolu var mı? Pek çok gömülü sistem bu tür türleri kullanır (genellikle tanımlayıcı kullanılarak bildirilir bit). Örneğin, orta düzey bir PIC'de if (bitVar1) bitVar2=1;iki talimat olacaktır; için en uygun kodlama if (byteVar1) byteVar2=1;en az dört olacaktır (birçok derleyicide muhtemelen beş). Bu tür türler, böylece büyük bir performans artışı sağlayabilir.
supercat

17

C standardının 6.5.8.6 bölümü şunları söylüyor:

<(Küçüktür),> (büyüktür), <= (küçüktür veya eşittir) ve> = (büyüktür veya eşittir) operatörlerinin her biri, belirtilen ilişki doğruysa 1 ve eğer 0 ise 0 verecektir. false.) Sonuç int türüne sahiptir.


Referans için teşekkürler. Öyle görünüyor ki, tarihsel nedenlerden dolayı doğru == 1.
pic11

2

Int to bool cast işlemi dolaylı olarak yapıldığından herhangi bir sorun yok gibi görünüyor. Bu, Microsoft Visual C ++, GCC ve Intel C ++ derleyicisinde çalışır. C veya C ++ 'da sorun yok.


2
"Bazı durumlarda işe yarar", özellikle bu araçların belirtilmemiş sürümlerinde doğruluğu kontrol etmenin iyi bir yolu değildir. Diğer cevaplarda yaklaşımı tercih ediyorum; belirli bir uygulamanın doğru olduğunu garanti edemezler, ancak doğru bir uygulamanın ne yapacağını garanti edebilirler.
Matthew
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.