Mengapa '&&' dan bukan '&'?

135

Mengapa &&lebih disukai daripada &dan ||lebih disukai |?

Saya bertanya kepada seseorang yang telah memprogram selama bertahun-tahun dan penjelasannya adalah:

Misalnya, dalam if (bool1 && bool2 && bool3) { /*DoSomething*/ }, bool1harus benar agar dapat menguji bool2mana yang harus benar sebelum melanjutkan ke bool3, dll. Jika saya menggunakan satu &saja, tidak ada urutan untuk pengujian bahkan jika semuanya harus benar untuk maju ke baris berikutnya, jadi mengapa itu penting?

Catatan: Saya ingin menunjukkan bahwa saya adalah pemograman yang setara dengan balita dan ini bukan pertanyaan serius atau mendesak. Ini lebih merupakan masalah memahami mengapa sesuatu harus dilakukan dengan cara tertentu dan bukan dengan cara lain.

Dani
sumber
55
& dan && | dan || adalah operator yang sama sekali berbeda
Felice Pollano
3
Ditandai ulang, karena ini tidak hanya berlaku untuk C #
Jonathan Dickinson
12
Dikembalikan, karena jawabannya sudah spesifik untuk C # dan cara kerja bagian dalamnya mungkin sedikit berbeda dalam bahasa lain yang umumnya memiliki konsep yang sama.
Daniel Hilgarth
8
@Felice: Mereka berbeda, tetapi hampir tidak sepenuhnya berbeda. Mereka sebenarnya sangat mirip: x & ydan x && yakan selalu dievaluasi ke hasil yang sama jika x dan y adalah ekspresi tipe boolean. Nyatanya, satu-satunya perbedaan dalam kasus itu tampaknya adalah bahwa dalam x & y, y selalu dievaluasi.
Joren
1
@slawekin: Saya sarankan untuk membaca seluruh jawaban. Beberapa secara ekstensif menulis tentang perbedaan kinerja. Jawabannya mungkin akan mengejutkan Anda.
Abel

Jawaban:

183

Dalam kebanyakan kasus, &&dan ||lebih disukai daripada &dan |karena yang pertama korsleting, artinya evaluasi dibatalkan segera setelah hasilnya jelas.

Contoh:

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

Jika CanExecutedikembalikan false, ekspresi lengkapnya akan false, terlepas dari nilai yang dikembalikan CanSave. Karena itu, CanSavetidak dieksekusi.

Ini sangat berguna dalam situasi berikut:

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

TryGetValuekembali falsejika kunci yang disediakan tidak ditemukan dalam kamus. Karena sifat hubungan pendek &&, value.Contains("test")hanya dijalankan, ketika TryGetValuekembali truedan dengan demikian valuetidak null. Jika Anda akan menggunakan operator bitwise AND& , Anda akan mendapatkan a NullReferenceExceptionjika kunci tidak ditemukan dalam kamus, karena bagian kedua dari ekspresi dieksekusi dalam kasus apa pun.

Contoh serupa tetapi lebih sederhana dari ini adalah kode berikut (seperti yang disebutkan oleh TJHeuvel):

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

CanExecutehanya dijalankan jika optidak null. Jika opadalah null, bagian pertama dari ekspresi ( op != null) mengevaluasi ke falsedan evaluasi sisanya (op.CanExecute() ) adalah dilewati.

Terlepas dari ini, secara teknis, mereka berbeda, juga:
&&dan ||hanya dapat digunakan pada boolsedangkan &dan |dapat digunakan pada setiap tipe integral ( bool, int, long, sbyte, ...), karena mereka adalah operator bitwise. &adalah bitwise AND operator dan |adalah bitwise OR operator.

Tepatnya, di C #, operator tersebut ( &, |[dan ^]) disebut "Operator logika" (lihat spesifikasi C # , bab 7.11). Ada beberapa implementasi dari operator ini:

  1. Untuk bilangan bulat ( int, uint, longdan ulong, Bab 7.11.1):
    Mereka diimplementasikan untuk menghitung hasil bitwise dari operan dan operator, yaitu &adalah menerapkan untuk menghitung bitwise logisAND dll
  2. Untuk pencacahan (bab 7.11.2):
    Mereka dilaksanakan untuk melakukan operasi logis dari jenis pencacahan yang mendasari.
  3. Untuk bools dan bool nullable (bab 7.11.3 dan 7.11.4):
    Hasilnya tidak dihitung menggunakan kalkulasi bitwise. Hasilnya pada dasarnya dicari berdasarkan nilai dari dua operan, karena jumlah kemungkinannya sangat kecil.
    Karena kedua nilai digunakan untuk pencarian, implementasi ini tidak mengalami hubungan arus pendek.
Daniel Hilgarth
sumber
31
Ini juga dapat berguna untuk memeriksa apakah ada sesuatu yang nol. Sebagai contoh: if(op != null && op.CanExecute()). Karena penyebab kedua tidak dievaluasi saat isnt pertama tidak benar, ini valid.
TJHeuvel
2
@TJHeuvel: Ini pada dasarnya adalah penggunaan yang sama yang saya jelaskan dengan TryGetValuecontoh saya . Tapi ya, itu contoh bagus lainnya.
Daniel Hilgarth
4
Jawaban yang bagus. Mungkin Anda juga harus menambahkan contoh bagaimana &atau |digunakan dengan argumen non-bool (yaitu apa yang dilakukan operator) untuk kepentingan semua orang baru.
Zabba
81

Untuk menjelaskan dengan sangat jelas apa artinya ini (meskipun jawaban lain mengisyaratkan - tetapi mungkin menggunakan terminologi yang tidak Anda mengerti).

Kode berikut:

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

Benar-benar dikompilasi untuk ini:

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

Di mana kode berikut dikompilasi persis seperti yang diwakili:

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

Ini disebut korsleting. Secara umum Anda harus selalu menggunakan &&dan ||dalam kondisi Anda.

Tanda Bonus: Ada satu skenario yang seharusnya tidak Anda lakukan. Jika Anda berada dalam situasi di mana kinerja sangat penting (dan ini penting nano-detik ) hanya gunakan hubungan pendek ketika Anda harus (misalnya nullmemeriksa) - karena hubungan pendek adalah cabang / lompatan; yang dapat mengakibatkan kesalahan prediksi cabang pada CPU Anda; sebuah &jauh lebih murah daripada &&. Ada juga skenario di mana arus pendek benar-benar dapat memutus logika - lihat jawaban saya ini.

Diatribe / Monologue : Mengenai kesalahan prediksi cabang yang diabaikan dengan sangat bahagia. Mengutip Andy Firth (yang telah mengerjakan game selama 13 tahun): "Ini mungkin level yang lebih rendah dari yang orang-orang pikir mereka harus pergi ... tapi mereka salah. Memahami bagaimana perangkat keras yang Anda pemrograman untuk memperlakukan cabang dapat mempengaruhi kinerja ke tingkat BESAR ... jauh lebih dari yang mungkin dihargai oleh kebanyakan pemrogram re: kematian oleh seribu pemotongan. "

  • Pengembang game (dan orang lain yang bekerja dalam kondisi waktu nyata yang ekstrem) sejauh merestrukturisasi logika mereka agar lebih sesuai dengan prediktor. Ada juga bukti ini dalam kode mscorlib yang didekompilasi.
  • Hanya karena .NET melindungi Anda dari hal semacam ini tidak berarti itu tidak penting. Salah prediksi cabang sangat mahal pada 60 Hz; atau 10.000 permintaan / detik.
  • Intel tidak akan memiliki alat untuk mengidentifikasi lokasi kesalahan prediksi, Windows juga tidak akan memiliki penghitung kinerja untuk ini, juga tidak akan ada kata untuk menggambarkannya, seandainya itu bukan masalah.
  • Ketidaktahuan tentang level dan arsitektur yang lebih rendah tidak membuat seseorang yang menyadarinya salah.
  • Selalu coba untuk memahami batasan perangkat keras yang Anda kerjakan.

Berikut adalah patokan bagi kafir. Yang terbaik adalah menjalankan proses dalam RealTime / High untuk mengurangi efek penjadwal: https://gist.github.com/1200737

Jonathan Dickinson
sumber
7
Tentang "tanda bonus": Kita semua tahu hal baik yang dihasilkan dari pengoptimalan prematur. :)
pengguna
6
@ Michael - itulah mengapa 'nano-detik penting' dicetak tebal :). Pengembang game AAA biasanya mengkhawatirkan hal-hal seperti ini - dan Anda tidak pernah tahu siapa yang akan membaca jawabannya; jadi selalu yang terbaik adalah mendokumentasikan bahkan kasus-kasus yang mendekati batas / ekstrim.
Jonathan Dickinson
1
Apakah tanda bonus itu berlaku untuk C #? Saya kira tidak, karena MSIL ditafsirkan, kecuali ekspresi dikompilasi sampai ke kode mesin.
Jeremy McGee
7
@Jeremy MSIL tidak diinterpretasikan.
Jonathan Dickinson
2
@TheD cek ulang jawaban - Saya telah menambahkan monolog tentang mengapa Anda HARUS khawatir tentang ini. Dan, FYI, (x && y)diterjemahkan ke LOAD x; BRANCH_FALSE; LOAD y; BRANCH_FALSE;mana (x & y)diterjemahkan menjadi LOAD x; LOAD y; AND; BRANCH_FALSE;. Satu cabang versus dua.
Jonathan Dickinson
68

Operator logika ( ||dan &&) vs. operator bitwise ( |dan &).

Perbedaan paling penting antara operator logika dan operator bitwise adalah bahwa operator logika mengambil dua boolean dan menghasilkan boolean sementara operator bitwise mengambil dua bilangan bulat dan menghasilkan bilangan bulat (catatan: bilangan bulat berarti tipe data integral apa pun, bukan hanya int).

Untuk menjadi bertele-tele, operator bitwise mengambil pola bit (mis. 01101011) dan melakukan sedikit DAN / ATAU pada setiap bit. Jadi, misalnya jika Anda memiliki dua bilangan bulat 8-bit:

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)

sedangkan operator logika hanya bekerja di bool:

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

Kedua, sering kali mungkin untuk menggunakan operator bitwise pada bool karena true dan false masing-masing setara dengan 1 dan 0, dan jika Anda menerjemahkan true ke 1 dan false ke 0, lalu lakukan operasi bitwise, lalu ubah bukan nol menjadi benar dan nol menjadi salah; Kebetulan hasilnya akan sama jika Anda baru saja menggunakan operator logika (periksa ini untuk latihan).

Perbedaan penting lainnya adalah bahwa operator logika dihubung pendek . Karenanya, di beberapa lingkaran [1], Anda sering melihat orang melakukan hal seperti ini:

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

yang diterjemahkan menjadi: "jika orang itu ada (yaitu bukan nol), cobalah untuk meninju dia, dan jika pukulan itu berhasil (yaitu kembali benar), maka lakukan tarian kemenangan" .

Jika Anda menggunakan operator bitwise, ini:

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

akan diterjemahkan menjadi: "jika orang itu ada (yaitu bukan nol) dan pukulan berhasil (yaitu mengembalikan nilai true), maka lakukan tarian kemenangan" .

Perhatikan bahwa di operator logika hubung pendek, person.punch()kode tidak dapat dijalankan sama sekali jika personnull. Faktanya, dalam kasus khusus ini, kode kedua akan menghasilkan kesalahan referensi nol jika personnol, karena mencoba memanggil person.punch()tidak peduli apakah orang itu nol atau tidak. Perilaku tidak mengevaluasi operan kanan ini disebut hubung singkat .

[1] Beberapa pemrogram akan menolak untuk menempatkan pemanggilan fungsi yang memiliki efek samping di dalam ifekspresi, sementara untuk pemrogram lain itu adalah ungkapan yang umum dan sangat berguna.

Karena operator bitwise bekerja pada 32-bit dalam satu waktu (jika Anda menggunakan mesin 32-bit), ini dapat menghasilkan kode yang lebih elegan dan lebih cepat jika Anda perlu membandingkan sejumlah besar kondisi, mis.

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`

Melakukan hal yang sama dengan operator logika akan membutuhkan banyak perbandingan:

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;

Contoh klasik di mana pola bit dan operator bitwise digunakan dalam izin sistem file Unix / Linux.

Lie Ryan
sumber
3
1 untuk sisi mempengaruhi masalah. Terkejut itu tidak disebutkan sebelumnya
Conrad Frix
3
contohnya tampak agak kasar, tetapi sepertinya jawaban lain terlalu berfokus pada korsleting dan tidak cukup pada perbedaan antara beroperasi pada bilangan bulat dan boolean.
R0MANARMY
Fungsi harus dipahami sebelum detail implementasi (short-circtuit / efek samping) mulai berlaku. Senang Anda menyelesaikan perbedaan utama menjadi logika boolean vs integer, bukan korsleting.
Abel
@ROMANARMY - kekerasan, saya suka ironi yang diberikan monkiker Anda. Kerja bagus
brumScouse
8

Dalam kasus:

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

akan bekerja seperti yang diharapkan.

Tapi:

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

berpotensi memunculkan pengecualian referensi null.

berlemak
sumber
2

Singkat dan sederhana:

1 && 2= benar
karena
1 = benar (bukan nol) di C
2 = benar (bukan nol) di C

trueANDS secara logis dengan truememberi true.

Tapi

1 & 2= 0 = false
karena
1 = 0001 dalam biner
2 = 0010 dalam biner

0001 ANDs bitwise dengan 0010 menghasilkan 0000 = 0 dalam desimal.

Begitu juga untuk || dan | operator juga ...!

Shrey
sumber
2
-1: Kita berbicara tentang C # di sini ... 1 && 2ilegal di C #
Daniel Hilgarth
Tetapi ini adalah contoh yang sangat penting yang menjelaskan mengapa Anda tidak bisa begitu saja bertukar & dan && (yang tampaknya dipikirkan banyak orang).
bobobobo
1

&&adalah versi sirkuit pendek dari &.

Jika kita mengevaluasi false & true, kita sudah tahu dari argumen pertama bahwa hasilnya akan salah. The &&versi operator akan mengembalikan hasil secepat itu bisa, daripada mengevaluasi ekspresi keseluruhan. Ada juga versi |operator yang serupa ||,.

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

aman

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

akan macet jika daftar tidak memiliki ukuran yang tepat.

jalf
sumber
Saya tidak dapat membayangkan seseorang dapat menulis "if (list.Count ()> 14 & list [14] ==" foo ")" daripada "if (list.Count ()> 14 && list [14] ==" foo ")". & secara sederhana dan alami tidak dapat digunakan untuk && dalam kasus ini meskipun & pasti aman (daftar [1] misalnya).
Tien Do
1

C # Operator harus menjelaskan alasannya:

Pada dasarnya memiliki dua &atau |'s berarti itu bersyarat daripada logis, sehingga Anda dapat membedakan antara keduanya.

& Operator memiliki contoh untuk menggunakannya&.

Stuart Thomson
sumber
Kedua link (efektif) rusak (dialihkan ke "Visual Studio 2005 Retired dokumentasi" ).
Peter Mortensen
1

Oke, secara nominal

    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);

menghasilkan jawaban yang sama. Namun, seperti yang Anda tunjukkan, jika Anda memiliki pertanyaan yang lebih kompleks, jadi:

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

Jika atidak benar dan mungkin bmerupakan fungsi yang harus dimatikan, sambungkan ke sesuatu, dapatkan ini, lakukan itu, buat keputusan .. mengapa repot-repot? Buang-buang waktu, Anda tahu itu sudah gagal. Mengapa membuat mesin mati dan melakukan pekerjaan ekstra yang tidak berguna?

Saya selalu menggunakan &&karena saya mengutamakan yang paling mungkin gagal, ergo, lebih sedikit perhitungan sebelum melanjutkan ketika tidak ada gunanya. Jika tidak ada cara untuk memprediksi pilihan yang kurang mungkin, seperti Anda memiliki boolean untuk membatasi keluaran data, sesuatu seperti:

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

Jika tidak limit, jangan repot-repot memeriksa kunci, yang bisa memakan waktu lebih lama ..

BugFinder
sumber
1

Ketika digunakan dalam ekspresi logis seperti pernyataan if &&lebih disukai karena akan berhenti mengevaluasi ekspresi segera setelah hasil salah pertama ditemukan. Ini dimungkinkan karena nilai salah akan menyebabkan seluruh ekspresi menjadi salah. Demikian pula (dan lagi dalam ekspresi logis)|| lebih disukai karena ini akan berhenti mengevaluasi ekspresi segera setelah menemukan ekspresi yang benar karena nilai benar apa pun akan menyebabkan seluruh ekspresi menjadi benar.

Namun, jika ekspresi menjadi atau-ed atau dan-ed bersama-sama memiliki efek samping, dan Anda ingin semua ini terjadi sebagai hasil dari ekspresi Anda (terlepas dari hasil ekspresi logis), maka &dan |dapat digunakan. Sebaliknya, operator &&dan ||dapat berguna sebagai pelindung dari efek samping yang tidak diinginkan (seperti pointer nol yang menyebabkan pengecualian dilempar).

Itu & dan |operator juga dapat digunakan dengan bilangan bulat dan dalam hal ini mereka menghasilkan hasil bilangan bulat yang merupakan dua operan dan-ed atau atau-ed bersama-sama di tingkat bit. Ini dapat berguna ketika bit biner nilai integer digunakan sebagai larik nilai benar dan salah. Untuk menguji apakah bit tertentu aktif atau nonaktif, bit-mask adalah bitwise dan diberi nilai. Untuk menyalakannya sedikit, topeng yang sama dapat diberi bitwise atau diberi nilai. Akhirnya untuk mematikan sedikit, pelengkap bitwise (penggunaan ~) topeng adalah bitwise dan-ed dengan nilainya.

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

Dalam bahasa selain C #, harus berhati-hati dengan mode logis versus bitwise dari & dan |. Pada kode di atas, fileif ekspresi kondisional pernyataan (a & 4) != 0adalah cara yang aman untuk mengekspresikan kondisi ini, tetapi dalam banyak bahasa seperti C, pernyataan bersyarat dapat dengan mudah memperlakukan nilai bilangan bulat nol sebagai nilai bilangan bulat salah dan bukan nol sebagai benar. (Alasan untuk ini berkaitan dengan instruksi prosesor cabang bersyarat yang tersedia, dan hubungannya dengan bendera nol yang diperbarui setelah setiap operasi bilangan bulat.) Jadi ìf, pengujian pernyataan untuk nol dapat dihapus dan kondisi dapat dipersingkat menjadi (a & 4).

Hal ini dapat menyebabkan kebingungan dan bahkan mungkin masalah ketika ekspresi digabungkan menggunakan bitwise dan operator mengembalikan nilai yang tidak memiliki bit yang berbaris. Pertimbangkan contoh berikut di mana efek samping dari dua fungsi diinginkan, sebelum memeriksa apakah keduanya berhasil (sebagaimana didefinisikan oleh mereka mengembalikan nilai bukan nol):

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

Di C, jika foo()mengembalikan 1 danbar() mengembalikan 2, "sesuatu" tidak akan dilakukan karena 1 & 2nol.

C # membutuhkan pernyataan kondisional seperti ifmemiliki oeprand boolean, dan bahasa tidak mengizinkan nilai integer untuk dimasukkan ke nilai boolean. Jadi kode di atas akan menghasilkan kesalahan kompiler. Ini akan lebih tepat diungkapkan sebagai berikut:

if (foo() != 0 & bar() != 0) {
    // do something
}
graza.dll
sumber
1

Jika Anda adalah programmer C lama, berhati-hatilah . C # benar-benar mengejutkan saya.

MSDN mengatakan untuk |operator:

Biner | operator ditentukan sebelumnya untuk tipe integral dan bool . Untuk tipe integral, | menghitung bitwise OR dari operannya. Untuk operan bool, | menghitung OR logis dari operannya; artinya, hasilnya salah jika dan hanya jika kedua operannya salah.

(Penekanan adalah milik saya.) Jenis Boolean ditangani secara khusus, dan dalam konteks ini pertanyaannya hanya mulai masuk akal, dan perbedaannya adalah, seperti yang telah dijelaskan lainnya dalam jawaban mereka:

&&dan ||mengalami korsleting. &dan |mengevaluasi kedua operan.

dan apa yang lebih disukai tergantung pada banyak hal seperti efek samping, kinerja, dan keterbacaan kode, tetapi umumnya operator hubungan pendek lebih disukai juga karena mereka lebih dipahami oleh orang-orang dengan latar belakang serupa seperti saya.

Alasannya adalah: Saya akan berargumen seperti ini: Karena tidak ada tipe boolean nyata di C, Anda dapat menggunakan operator bitwise |dan hasilnya dievaluasi sebagai benar atau salah dalam kondisi if. Tapi ini sikap yang salah untuk C #, karena sudah ada kasus khusus untuk tipe boolean.

nalply
sumber
0

Ini penting, karena jika biaya evaluasi bool2 (misalnya) tinggi tetapi bool1 salah, Anda telah menghemat sedikit komputasi dengan menggunakan && over &

pemboros
sumber
0

Karena &&dan ||digunakan untuk kontrol aliran seperti apa if/elseadanya. Ini tidak selalu tentang persyaratan. Masuk akal untuk menulis sebagai pernyataan, bukan sebagai ifatau whilebersyarat, berikut ini:

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

atau bahkan

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

Bukan hanya karena if/elseversi tersebut lebih mudah diketik daripada versi yang setara ; mereka juga lebih mudah dibaca dan dipahami.

tchrist
sumber
0

&& dan & berarti dua hal yang sangat berbeda dan memberi Anda dua jawaban yang berbeda.

1 && 2menghasilkan 1 ("true")
1 & 2menghasilkan 0 ("false")

&&adalah operator logika - itu berarti "benar jika kedua operan benar"
&adalah perbandingan bitwise. Artinya "beri tahu saya bit mana yang disetel di kedua operan"

tylerl
sumber
2
Pertanyaannya adalah tentang C #. Dalam C #, tidak ada cara untuk mentransmisikan angka ke bool, jadi 0 bukan 'salah' dan bukan nol bukan 'benar'; tidak ada persamaan.
Nate CK
Untuk mengonversi bilangan menjadi bool, dengan cara 1 berarti benar dan 0 berarti salah, katakan "n! = 0" (Saya berasumsi ... saya tidak terlalu paham dengan C #). Sebenarnya saya ingin mencabut komentar ini karena tidak diteliti dengan baik dan menurut saya komentar ini tidak membantu atau benar-benar relevan dengan komentar sebelumnya karena sekarang saya memikirkannya lebih dalam, tetapi saya tidak sengaja menekan enter dan sekarang saya rasa saya tidak bisa batalkan jadi di sini ya pergi, untuk apa pun nilainya :-)
Don Hatch
1 && 2memberikan kesalahan kompiler: "Kesalahan 4 Operator '&&' tidak dapat diterapkan ke operan jenis 'int' dan 'int'"
Peter Mortensen
0

Cara tercepat (dan sedikit bodoh) untuk menjelaskan ini kepada orang-orang yang tidak PERLU mengetahui operasi kode yang tepat saat melakukan ini adalah

&& sedang memeriksa masing-masing kondisi tersebut Hingga menemukan salah dan mengembalikan seluruh hasil sebagai salah

|| sedang memeriksa masing-masing kondisi tersebut Hingga menemukan nilai benar dan mengembalikan keseluruhan hasil sebagai benar.

& sedang melakukan apon berbasis MATHS KEDUA / SEMUA kondisi dan menangani hasilnya.

| sedang melakukan apon berbasis MATHS KEDUA / SEMUA kondisi dan menangani hasilnya.

Saya tidak pernah menemukan titik di mana saya perlu menggunakan & atau |dalam pernyataan if. Saya kebanyakan menggunakannya untuk memotong nilai Heksadesimal menjadi warna komponennya menggunakan pergeseran bitwise.

MISALNYA:

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

Dalam operasi ini "& 0xFF" memaksa untuk hanya melihat nilai biner. Saya pribadi belum menemukan kegunaan untuk | Namun demikian.

CACING
sumber
0

Secara sederhana,

if exp1 && exp2

jika exp1 adalah flase jangan centang exp2

tapi

if exp1 & exp2

jika exp1 adalah falseAtau true periksa exp2

dan jarang orang menggunakan &karena mereka jarang ingin memeriksa exp2 jika exp1 adalahfalse

Fady
sumber