Neden '&' değil '&&'?


135

Neden &&tercih edilir &ve ||tercih edilir |?

Yıllardır program yapan birine sordum ve açıklaması:

Örneğin, içinde if (bool1 && bool2 && bool3) { /*DoSomething*/ }, bool1devam bool2etmeden önce hangisinin doğru olması gerektiğini test etmesi için doğru olması gerekir bool3. &Bunun yerine tek bir tane kullansaydım, hepsinin doğru olması gerekse bile test için bir düzen yoktur. bir sonraki satıra geçelim, peki neden önemli?

Not: Bir yürümeye başlayanın programlama eşdeğeri olduğumu belirtmek isterim ve bu ciddi veya acil bir soru değil. Bu daha çok şeylerin neden bir başkasına kıyasla belirli bir şekilde yapılması gerektiğini anlamak meselesidir.


55
& ve && | ve || tamamen farklı operatörler
Felice Pollano

3
Yeniden etiketlendi, çünkü bu sadece C # için geçerli değil
Jonathan Dickinson

12
Geri döndü, çünkü cevaplar zaten C # 'a özgüdür ve iç çalışma genellikle aynı konsepte sahip diğer dillerde biraz farklı olabilir.
Daniel Hilgarth

8
@Felice: Farklılar, ama neredeyse tamamen farklı değiller . Aslında çok benzerler: x & yve x && yeğer x ve y boole tipinin ifadeleri ise her zaman aynı sonucu değerlendirecektir. Aslında bu durumda tek fark x & y, y'nin her zaman değerlendirildiği gibi görünmektedir .
Joren

1
@slawekin: Cevapları okumanızı öneririm. Bazıları performans farklılıkları hakkında kapsamlı yazılar yazmaktadır. Cevap sizi şaşırtabilir.
Abel

Yanıtlar:


183

Çoğu durumda, &&ve ||tercih edilir &ve |birincisi kısa devre olduğu için, sonuç netleşir değerlendirilmez değerlendirme iptal edilir.

Misal:

if(CanExecute() && CanSave())
{
}

Eğer CanExecutegetiri false, tam ifadesi olacaktır falsebakılmaksızın dönüş değeri, CanSave. Bu nedenle, CanSaveyürütülmez.

Bu, aşağıdaki durumlarda çok kullanışlıdır:

string value;
if(dict.TryGetValue(key, out value) && value.Contains("test"))
{
    // Do Something
}

TryGetValuefalseverilen anahtar sözlükte bulunmazsa döndürür . Kısa devre yapısından dolayı &&, value.Contains("test")sadece TryGetValuegeri döndüğünde trueve dolayısıyla valueyapılmadığında yürütülür null. Kullanmak istiyorsanız ikilik VE operatörü &yerine, bir alacağı NullReferenceExceptionanahtar sözlükte bulunmazsa ifade ikinci bölümü her durumda yürütülür çünkü.

Buna benzer ama daha basit bir örnek aşağıdaki koddur (TJHeuvel tarafından belirtildiği gibi):

if(op != null && op.CanExecute())
{
    // Do Something
}

CanExecutekeşke yürütülür opdeğildir null. Öyleyse op, null( op != null) ifadesinin ilk kısmı falsekalanı ( op.CanExecute()) olarak değerlendirilir ve geri kalanı ( ) değerlendirilirse atlanır.

Bunun dışında, teknik olarak, onlar da farklıdır:
&&ve ||yalnızca kullanılabilir booloysa &ve |herhangi ayrılmaz türü (kullanılabilir bool, int, long, sbytebunlar bitsel operatörleri, çünkü, ...). &olduğu lojik AND operatörü ve |bir bit düzeyinde VEYA operatörü.

Çok açık olmak gerekirse, C # 'da bu işleçlere ( &, |[ve ^]) "Mantıksal işleçler" denir (bkz. C # özellikleri , bölüm 7.11). Bu operatörlerin birkaç uygulaması vardır:

  1. Tamsayıları için ( int, uint, longve ulong, bölüm 7.11.1):
    Bunlar işlenen ve operatörün bitsel sonucu hesaplamak için uygulanmaktadır, yani &bit düzeyinde mantıksal hesaplamak için uygulamak olduğunu ANDvb
  2. Numaralandırmalar için (bölüm 7.11.2):
    Altta yatan numaralandırma tipinin mantıksal çalışmasını gerçekleştirmek için uygulanırlar.
  3. Bools ve nullable bools için (bölüm 7.11.3 ve 7.11.4):
    Sonuç, bitsel hesaplamalar kullanılarak hesaplanmaz. Sonuç temel olarak iki işlenenin değerlerine göre araştırılır, çünkü olasılıkların sayısı çok azdır.
    Her iki değer de arama için kullanıldığından, bu uygulama kısa devre yapmaz.

31
Bu, bir şeyin boş olup olmadığını kontrol etmek için de kullanışlı olabilir. Örneğin: if(op != null && op.CanExecute()). İkinci neden birinci doğru olmadığında değerlendirilmediğinden, bu geçerlidir.
TJHeuvel

2
@TJHeuvel: Bu, temelde benim örneğimle anlattığım aynı kullanım TryGetValue. Ama evet, bunun iyi bir örneği.
Daniel Hilgarth

4
İyi cevap. Belki de yeni olmayan herkesin yararına bool olmayan argümanlarla (yani operatörlerin yaptıkları) nasıl &veya |kullanıldığına dair bir örnek eklemelisiniz .
Zabba

81

Bunun ne anlama geldiğini çok açık bir şekilde açıklamak için (diğer cevaplar ipucu vermesine rağmen - muhtemelen anlamadığınız terminolojiyi kullanın).

Aşağıdaki kod:

if (a && b)
{
   Foo();
}

Gerçekten bunun için derlenmiştir:

if (a)
{
    if (b)
    {
        Foo();
    }
}

Aşağıdaki kod tam olarak temsil edildiği gibi derlenir:

if (a & b)
{
   Foo();
}

Buna kısa devre denir. Genel olarak daima &&ve ||koşullarınızda kullanmalısınız .

Bonus İşaretler: Yapmamanız gereken bir senaryo var. Performansın çok önemli olduğu (ve bu nano-saniyelerin çok önemli olduğu ) bir durumdaysanız, yalnızca gerektiğinde (örneğin nullkontrol) kısa devre kullanın - kısa devre bir dal / sıçrama olduğundan; CPU'nuzda bir şube yanlış algılanmasına neden olabilir; an &çok daha ucuzdur &&. Kısa devrelerin gerçekten mantığı kırabileceği bir senaryo da var - bu cevabıma bir göz atın .

Diatribe / Monologue : En mutlulukla görmezden gelen şube yanlış tahminiyle ilgili. Andy Firth'dan (13 yıldır oyunlar üzerinde çalışıyor) alıntı : "Bu, insanların gitmeleri gerektiğini düşündükleri daha düşük bir seviye olabilir ... ama yanlış olurlar. Dallar için programladığınız donanımın nasıl davranabileceğini anlamak performansı BÜYÜK bir dereceye kadar etkiler ... programcıların çoğunun yeniden: ölümü bin kesintiyle takdir edebileceğinden çok daha fazla. "

  • Oyun geliştiricileri (ve aşırı gerçek zamanlı koşullarda çalışan diğerleri), yordayıcıya daha iyi uyacak şekilde mantıklarını yeniden yapılandırmaya kadar giderler. Ayrıştırılmış mscorlib kodunda bunun kanıtı da vardır.
  • .NET'in sizi bu tür şeylerden koruduğu önemli olmadığı anlamına gelmez. Bir dalın yanlış tahmini 60 Hz'de çok pahalıdır; veya saniyede 10.000 istekte.
  • Intel'in yanlış tahminlerin yerini belirleyecek araçlara sahip olmayacağı gibi, Windows'un bunun için bir performans sayacı ya da bir sorun olmasa da bunu açıklayacak bir kelime olmazdı.
  • Düşük seviyeler ve mimarlık hakkındaki cehalet, onların farkında olan birini yanlış yapmaz.
  • Her zaman üzerinde çalıştığınız donanımın sınırlamalarını anlamaya çalışın.

İşte inanmayanlar için bir kriter. Zamanlayıcıyı bir etkiyi azaltmak için işlemi RealTime / High'da çalıştırmak en iyisidir: https://gist.github.com/1200737


7
"Bonus işaretleri" hakkında: Hepimiz erken optimizasyondan çıkan iyiliği biliyoruz. :)
bir CVn

6
@Michael - bu yüzden 'nano saniye kritik' koyu renktedir :). AAA oyun geliştiricileri genellikle böyle şeyler için endişelenir - ve cevapları kimin okuyacağını asla bilemezsiniz; bu nedenle sınırda / uç noktalarda bile belgelemek her zaman en iyisidir.
Jonathan Dickinson

1
Bu bonus işareti C # için geçerli mi? Ifade makine koduna kadar derlenmedikçe, MSIL yorumlandığı gibi düşünmemiştim.
Jeremy McGee

7
@Jeremy MSIL yorumlanmaz.
Jonathan Dickinson

2
@TheD recheck answer - Neden bu konuda endişelenmeniz gerektiğine dair bir monolog ekledim. Ve, FYI, (x && y)tercüme ettiği LOAD x; BRANCH_FALSE; LOAD y; BRANCH_FALSE;yere (x & y)çevirir LOAD x; LOAD y; AND; BRANCH_FALSE;. Bir dal ikiye karşı.
Jonathan Dickinson

68

Mantıksal işleç ( ||ve &&) ve bitsel işleç ( |ve &) karşılaştırması.

Bir mantıksal operatör ile bitsel operatör arasındaki en önemli fark, bir mantıksal operatörün iki boolean alması ve bir boolean üretmesi , bitsel bir operatörün iki tamsayı alması ve bir tamsayı üretmesidir (not: tamsayılar sadece int değil, herhangi bir entegre veri türü anlamına gelir).

Bilgiçlikçi olmak için, bitsel bir operatör bir bit paterni alır (örn. 01101011) ve her bitte biraz bilge bir AND / OR yapar. Örneğin, iki adet 8 bitlik tam sayınız varsa:

a     = 00110010 (in decimal:    32+16+2   = 50)
b     = 01010011 (in decimal: 64+   16+2+1 = 83)
----------------
a & b = 00010010 (in decimal:       16+2   = 18)
a | b = 01110011 (in decimal: 64+32+16+2+1 = 115)

mantıksal bir işleç yalnızca şu koşullarda çalışır bool:

a      = true
b      = false
--------------
a && b = false
a || b = true

İkincisi, doğru ve yanlış sırasıyla 1 ve 0'a eşdeğer olduğu için bool üzerinde bitsel bir operatör kullanmak genellikle mümkündür ve true değerini 1'e ve false değerini 0'a çevirirseniz, bitsel işlem yaparsanız, sıfırdan farklı bir dönüşüme neden olur. doğru, sıfır doğru yanlış; mantıksal işleç kullanmış olsaydınız sonuç aynı olacaktır (egzersiz için bunu kontrol edin).

Bir diğer önemli ayrım da mantıksal bir operatörün kısa devre yapmasıdır . Böylece, bazı çevrelerde [1], insanların genellikle böyle bir şey yaptığını görürsünüz:

if (person && person.punch()) {
    person.doVictoryDance()
}

hangi çevirir: "Kişi (yani boş değil) varsa, ona / onu yumruk çalışın ve delgi (doğru yani getiri) başarılı olursa, o zaman bir zafer dansı yapmak" .

Bunun yerine bitsel bir operatör kullandıysanız, bu:

if (person & person.punch()) {
    person.doVictoryDance()
}

çevirecektir: "Kişi varsa (yani boş değil) ve delgi (true yani getiri), sonra bir zafer dansı yapmak başarılı" .

Kısa devreli mantıksal işleçte, person.punch()boşsa kodun hiç çalıştırılmayabileceğini unutmayın person. Aslında, bu özel durumda, ikinci kod null olduğunda null referans hatası üretecektir person, çünkü person.punch()kişi null olup olmadığına bakılmaksızın çağırmaya çalışır . Doğru işleneni değerlendirmemeye yönelik bu davranışa kısa devre denir .

[1] Bazı programcılar, bir ififadenin içinde yan etkisi olan bir işlev çağrısı koymak için baulk yaparken, diğerleri için bu yaygın ve çok yararlı bir deyimdir.

Bitsel bir operatör bir seferde 32 bit üzerinde çalıştığından (32 bit bir makinedeyseniz), çok sayıda koşulu karşılaştırmanız gerekirse daha zarif ve daha hızlı bir koda yol açabilir, örn.

int CAN_PUNCH = 1 << 0, CAN_KICK = 1 << 1, CAN_DRINK = 1 << 2, CAN_SIT = 1 << 3,
    CAN_SHOOT_GUNS = 1 << 4, CAN_TALK = 1 << 5, CAN_SHOOT_CANNONS = 1 << 6;

Person person;
person.abilities = CAN_PUNCH | CAN_KICK | CAN_DRINK | CAN_SIT | CAN_SHOOT_GUNS;

Place bar;
bar.rules = CAN_DRINK | CAN_SIT | CAN_TALK;

Place military;
military.rules = CAN_SHOOT_CANNONS | CAN_PUNCH | CAN_KICK | CAN_SHOOT_GUNS | CAN_SIT;

CurrentLocation cloc1, cloc2;
cloc1.usable_abilities = person_abilities & bar_rules;
cloc2.usable_abilities = person_abilities & military_rules;

// cloc1.usable_abilities will contain the bit pattern that matches `CAN_DRINK | CAN_SIT`
// while cloc2.usable_abilities will contain the bit pattern that matches `CAN_PUNCH | CAN_KICK | CAN_SHOOT_GUNS | CAN_SIT`

Aynı şeyi mantıksal işleçlerle yapmak, çok miktarda karşılaştırma gerektirecektir:

Person person;
person.can_punch = person.can_kick = person.can_drink = person.can_sit = person.can_shoot_guns = true;
person.can_shoot_cannons = false;

Place bar;
bar.rules.can_drink = bar.rules.can_sit = bar.rules.can_talk = true;
bar.rules.can_punch = bar.rules.can_kick = bar.rules.can_shoot_guns = bar.rules.can_shoot_cannons = false;

Place military;
military.rules.can_punch = military.rules.can_kick = military.rules.can_shoot_guns = military.rules.can_shoot_cannons = military.rules.can_sit = true;
military.rules.can_drink = military.rules.can_talk = false;

CurrentLocation cloc1;
bool cloc1.usable_abilities.can_punch         = bar.rules.can_punch         && person.can_punch,
     cloc1.usable_abilities.can_kick          = bar.rules.can_kick          && person.can_kick,
     cloc1.usable_abilities.can_drink         = bar.rules.can_drink         && person.can_drink,
     cloc1.usable_abilities.can_sit           = bar.rules.can_sit           && person.can_sit,
     cloc1.usable_abilities.can_shoot_guns    = bar.rules.can_shoot_guns    && person.can_shoot_guns,
     cloc1.usable_abilities.can_shoot_cannons = bar.rules.can_shoot_cannons && person.can_shoot_cannons
     cloc1.usable_abilities.can_talk          = bar.rules.can_talk          && person.can_talk;

bool cloc2.usable_abilities.can_punch         = military.rules.can_punch         && person.can_punch,
     cloc2.usable_abilities.can_kick          = military.rules.can_kick          && person.can_kick,
     cloc2.usable_abilities.can_drink         = military.rules.can_drink         && person.can_drink,
     cloc2.usable_abilities.can_sit           = military.rules.can_sit           && person.can_sit,
     cloc2.usable_abilities.can_shoot_guns    = military.rules.can_shoot_guns    && person.can_shoot_guns,
     cloc2.usable_abilities.can_talk          = military.rules.can_talk          && person.can_talk,
     cloc2.usable_abilities.can_shoot_cannons = military.rules.can_shoot_cannons && person.can_shoot_cannons;

Bit kalıplarının ve bitsel operatörün kullanıldığı klasik bir örnek Unix / Linux dosya sistemi izinleridir.


3
Taraf için +1 sorunu etkiler. Daha önce bahsedilmemişti
Conrad Frix

3
örnek biraz şiddetli gözüküyor, ancak diğer cevaplar çok kısa devrelere çok fazla odaklanmış gibi görünüyor ve tamsayılarla booleanlar üzerinde çalışmak arasındaki farka yeterli değil.
R0MANARMY

Uygulama ayrıntıları (kısa devre / yan etkiler) devreye girmeden önce işlev anlaşılmalıdır. Ana farkı kısa devre değil, tamsayı mantığı ile boolean olarak temizlemenize sevindim.
Abel

@ROMANARMY - şiddet içeren, keşişinize verilen ironiyi seviyorum. Güzel iş
brumScouse

8

Bu durumuda:

if (obj != null && obj.Property == true) { }

beklendiği gibi çalışır.

Fakat:

if (obj != null & obj.Property == true) { }

potansiyel olarak bir boş referans istisnası atabilir.


2

Kısa ve basit:

1 && 2= true
çünkü
C = 1 (true (sıfır olmayan))
= C (true (sıfır olmayan))

trueANDS ile mantıksal trueolarak vermek true.

Fakat

1 & 2= 0 = yanlış
çünkü
1 = 0001, ikili
2 = 0010, ikili

0001 AND, ondalık olarak 0000 = 0 vermek için 0010 ile bitsel olarak.

Aynı şekilde || ve | operatörleri de ...!


2
-1: Burada C # hakkında konuşuyoruz ... C # ' 1 && 2da yasadışı
Daniel Hilgarth

Ama bu neden önemli olduğunu açıklayan son derece önemli bir örnek. basitçe değiş tokuş edemeyeceğinizi ve & & (birçok insanın düşündüğü gibi görünen).
bobobobo

1

&&kısa devre versiyonudur &.

Değerlendiriyorsak false & true, sonucun yanlış olacağını ilk argümana bakarak zaten biliyoruz. &&Operatörün sürümü bütün ifadeyi değerlendirmek yerine, en kısa sürede olabildiğince bir sonuç döndürecektir. |Operatörün benzer bir versiyonu da var ||.


1
if (list.Count() > 14 && list[14] == "foo")

güvenlidir

if (list.Count() > 14 & list[14] == "foo")

Liste doğru boyuta sahip değilse çökecektir.


Birisinin "if (list.Count ()> 14 && list [14] ==" yerine "if (list.Count ()> 14 & list [14] ==" foo ")" yazabileceğini hayal edemiyorum. foo ")". & 'sadece kesinlikle ve doğal olarak && için kesinlikle güvenli olmasa bile kullanılamaz (örneğin liste [1]).
Tien Do

1

C # Operatörler nedenini açıklamalıdır:

Esasen iki &'s' veya |'s, mantık yerine koşullu olduğu anlamına gelir, böylece ikisi arasındaki farkı anlayabilirsiniz.

& Operator bir tane kullanma örneğine sahiptir&.


Her iki bağlantı da (etkin bir şekilde) bozuk ( "Visual Studio 2005 Emekli belgeleri" ne yönlendirir ).
Peter Mortensen

1

Tamam, nominal değerde

    Boolean a = true;
    Boolean b = false;

    Console.WriteLine("a({0}) && b({1}) =  {2}", a, b, a && b);
    Console.WriteLine("a({0}) || b({1}) =  {2}", a, b, a || b);
    Console.WriteLine("a({0}) == b({1}) =  {2}", a, b, a == b);

    Console.WriteLine("a({0}) & b({1}) =  {2}", a, b, a & b);
    Console.WriteLine("a({0}) | b({1}) =  {2}", a, b, a | b);
    Console.WriteLine("a({0}) = b({1}) =  {2}", a, b, a = b);

aynı cevabı üretin. Ancak, gösterdiğiniz gibi, daha karmaşık bir sorunuz varsa:

if (a and b and c and d) ..

Doğru adeğilse ve belki de bgitmesi, bir şeye bağlanması, alması, bunu yapması, bir karar vermesi gereken bir işlevse .. neden rahatsız oluyorsunuz? Zaman kaybı, zaten başarısız olduğunu biliyorsun. Neden makineyi kapatmalı ve ekstra anlamsız işler yapmalısınız?

Her zaman kullandım &&çünkü ilk önce başarısız olma ihtimalini koydum, ergo, daha az hesaplama yapmadan önce hiçbir nokta olmadığında. Veri çıkışını sınırlamak için bir boole sahip gibi, daha az olası seçenekleri tahmin etmenin bir yolu yoksa, aşağıdaki gibi:

if (limit && !MyDictionary.ContainsKey("name")) 
    continue;

Eğer değilse limit , anahtarı kontrol etmekten çekinmeyin, bu da daha uzun sürebilir.


1

&&İlk yanlış sonuçla karşılaşıldığında ifadeleri değerlendirmeyi durduracağı için if ifadesi gibi mantıksal bir ifadede kullanıldığında . Yanlış bir değer tüm ifadenin yanlış olmasına neden olacağından bu mümkündür. Benzer şekilde (ve yine mantıksal ifadelerde)|| tercih edilir, çünkü gerçek bir ifadeyle karşılaşır karşılaşmaz ifadeleri değerlendirmeyi durduracaktır, çünkü herhangi bir gerçek değer tüm ifadenin doğru olmasına neden olacaktır.

Eğer bununla ifadeler-ed da ve-ed birlikte yan etkileri vardır ve siz (bakılmaksızın mantıksal ifadenin sonucu) İfadenin sonucu gerçekleşmesi Bunların hepsini istiyorum olmanın ardından &ve |kullanılabilir. Tersine, &&ve ||operatörleri istenmeyen yan etkilere karşı bir koruma olarak yararlı olabilir (bir istisnanın atılmasına neden olan bir boş gösterici gibi).

&Ve |operatörler de tam sayı ile kullanılabilir ve bu durumda iki işlenen ve-ed veya edilmemiş ya ed bit düzeyinde bir arada bir tamsayıdır sonucu üretmek edilebilir. Doğru ve yanlış değerler dizisi olarak bir tamsayı değerinin ikili bitleri kullanıldığında bu yararlı olabilir. Belirli bir bitin açık veya kapalı olup olmadığını test etmek için bit maskesi, değerle bitsel ve düzenlenir. Biraz açmak için, aynı maske değerle bitsel veya düzenlenebilir. Sonunda biraz kapatmak için, ~bir maskenin bitsel tamamlayıcısı (kullanılarak ) değerle bitlenir ve düzenlenir.

int a = 0; // 0 means all bits off
a = a | 4; // set a to binary 100
if ((a & 4) != 0) {
    // will do something
}
a = a & (~4) // turn bit off again, a is now 000

C # dışındaki dillerde, mantıksal ve bitsel modları & ve | Yukarıdaki kodda, ififadenin koşullu ifadesi (a & 4) != 0bu durumu ifade etmenin güvenli bir yoludur, ancak birçok C benzeri dilde koşullu ifadeler, sıfır tamsayı değerlerini yanlış ve sıfır olmayan tamsayı değerleri olarak doğru kabul edebilir. (Bunun nedeni, mevcut koşullu dal işlemcisi talimatları ve bunların her tamsayı işleminden sonra güncellenen sıfır bayrağıyla ilişkisi ile ilgilidir.) Böylece, ìfifadenin sıfır testi kaldırılabilir ve koşul kısaltılabilir (a & 4).

Bu, karışıklıklara neden olabilir ve ifadeler bitsel ve operatörün sıralanan bitleri olmayan operatör dönüş değerleri kullanılarak birleştirildiğinde bile sorunlara neden olabilir. Her ikisinin de başarılı olup olmadığını kontrol etmeden önce (sıfırdan farklı bir değer döndürerek tanımladıkları gibi) iki işlevin yan etkilerinin istendiği aşağıdaki örneği düşünün:

if (foo() & bar()) {
    // do something
}

C'de, foo()1 döndürür ve bar()2 döndürürse 1 & 2, sıfır olduğu için "bir şey" yapılmaz .

C #, ifbir boolean oeprand'a sahip olmak gibi koşullu ifadeler gerektirir ve dil, bir tamsayı değerinin bir boole değerine dönüştürülmesine izin vermez. Yani yukarıdaki kod derleyici hataları üretecektir. Daha doğru bir şekilde şu şekilde ifade edilir:

if (foo() != 0 & bar() != 0) {
    // do something
}

1

Eski bir zamanlayıcı C programcısıysanız, dikkatli olun . C # beni gerçekten şaşırttı.

MSDN| operatör için şunları söylüyor :

İkili | operatörler integral tipleri ve bool için önceden tanımlanmıştır . İntegral tipler için | işlenenlerinin bit yönünü VEYA hesaplar. Bool işlenenleri için | işlenenlerinin mantıksal OR'sini hesaplar; yani, sonuç yalnızca ve her iki işleneninin de yanlış olması durumunda yanlıştır.

(Vurgu benimdir.) Boole türleri özel olarak ele alınır ve bu bağlamda soru sadece mantıklı olmaya başlar ve fark, diğerlerinin cevaplarında zaten açıklandığı gibi:

&&ve ||kısa devre yapıyorlar. &ve her iki işleneni de| değerlendirin .

ve hangisinin tercih edileceği, yan etkiler, performans ve kod okunabilirliği gibi birçok şeye bağlıdır, ancak genellikle kısa devre operatörleri de benim gibi benzer arka plana sahip insanlar tarafından daha iyi anlaşıldığı için tercih edilir.

Sebebi şöyledir: C'de gerçek bir boole türü olmadığından, bitsel operatörünü kullanabilir |ve sonucunun bir if durumunda doğruluk veya falsi olarak değerlendirilmesini sağlayabilirsiniz. Ancak bu, C # için yanlış tutumdur, çünkü boole türleri için zaten özel bir durum vardır.


0

Bu önemlidir, çünkü eğer bool2 değerlendirme maliyeti yüksekse (bool1 yanlışsa), && over &


0

Çünkü &&ve ||olduğu gibi akış kontrolü için kullanılır if/else. Her zaman şartlarla ilgili değildir. Aşağıdaki gibi bir şart veya koşul olarak değil , bir ifade olarak yazmak kesinlikle mantıklıdır :ifwhile

 a() && b() && c() && d();

ya da

 w() || x() || y() || z();

Yazmak sadece eşdeğer if/elseversiyonlardan daha kolay değil ; ayrıca okumak ve anlamak çok daha kolaydır.


0

&& ve & iki çok farklı anlama gelir ve size iki farklı cevap verir.

1 && 2verim 1 ("doğru")
1 & 2verim 0 ("yanlış")

&&bir mantık operatörüdür - "her iki işlenen de doğruysa doğru" anlamına gelir
&bitsel bir karşılaştırma. "Bana her iki işlenende hangi bitlerin ayarlandığını söyle" anlamına gelir


2
Soru C # ile ilgili. C # 'da, bir sayıya boole dökmenin bir yolu yoktur, bu nedenle 0' false 'değildir ve sıfır olmayan' true 'değildir; basitçe denklik yoktur.
Nate CK

Sayıyı boole dönüştürmek için, 1 doğru ve 0 yanlış anlamına gelir, "n! = 0" deyin (sanırım ... C # 'a gerçekten aşina değilim). Aslında, iyi araştırılmamış olduğu için bu yorumu geri çekmek istedim ve şimdi daha fazla düşündüğüm için önceki yorumla ilgili yararlı veya gerçekten alakalı olduğunu düşünmüyorum, ancak yanlışlıkla enter tuşuna bastım ve şimdi yapabileceğimi sanmıyorum iptal edelim işte, ne pahasına olursa olsun :-)
Don Hatch

1 && 2derleyici hatası veriyor: "Hata 4 İşleci '&&', 'int' ve 'int' türündeki işlenenlere uygulanamaz"
Peter Mortensen

0

Bunu yaparken kodun tam işlemlerini bilmesi gerekmeyen kişilere bunu açıklamanın en hızlı (ve biraz aptalca) yolu

&& , bir yanlış bulana ve tüm sonucu yanlış olarak alana kadar bu koşulların her birini kontrol eder.

|| bir doğru bulana ve tüm sonucu doğru olarak döndürene kadar bu koşulların her birini kontrol eder.

& MATHS tabanlı apon BOTH / ALL koşullarını yapıyor ve sonuç ile ilgileniyor.

| MATHS temelli apon BOTH / ALL koşullarını yapıyor ve sonuçla ilgileniyor.

Hiç kullanmam gereken bir noktaya rastlamadım & veya | bir if ifadesi içinde. Ben çoğunlukla onaltılık değerleri kullanarak bileşen renklerine Onaltılık değerleri kesmek için kullanıyorum.

ÖRNEĞİN:

r = fullvalue >> 0xFF & 0xFF;
g = fullvalue >> 0xF & 0xFF;
b = fullvalue & 0xFF;

Bu işlem içinde "& 0xFF" sadece ikili değere bakmaya zorlar. Şahsen için bir kullanım bulamadım | yine de.


0

basitçe,

if exp1 && exp2

exp1 ise exp2'yi flase kontrol etmeyin

fakat

if exp1 & exp2

exp1 ise falseVeya exp2'yi true kontrol edin

ve nadiren insanlar kullanırlar &çünkü exp1 ise exp2'yi nadiren kontrol etmek isterlerfalse

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.