2014-11-11 15 views
5

Sadece kod gördüm ve ne kadar mantıklı anlamak için kuramıyorum ve burada "cout" ile davranır: Söz konusuAkış çıkışı ile hangi mantıksal AND işlemi çalışır?

int userInput = 9; // Suppose user input is 9. 
int remainder = 9 % 2; 
(remainder & 1 && std::cout<<"odd")|| cout<<"even"; 
+0

Burada bulunan parantez'e ihtiyacınız yoktur, ancak operatörün önceliğine bağlı olarak (hatırlayamıyorum), 'geri kalan' ve 'alt bileşenini parantez içine almanız gerekebilir. –

+0

Bkz. [C++ operatörü önceliği] (http://en.cppreference.com/w/cpp/language/operator_precedence) –

cevap

6

hattı:

(remainder & 1 && std::cout<<"odd") || cout<<"even"; 

aşağıdaki aynı mı

((remainder & 1) && (operator<<(std::cout, "odd").operator bool())) || (operator<<(std::cout, "even").operator bool()); 
: Eğer operatör öncelik ve dikkate operatör aşırı yüklenmeleri almak

std::cout (daha genel olarak, std::basic_ostream) tanımlı operator<<() ve operator bool() işleçleri tanımlanmıştır. İlk operatör bir std::basic_ostream& referansı, yani akışın kendisine bir referans (birlikte zincirleme işlemleri için yararlıdır) verir. İkinci operatör, akışın bir hata durumunda olup olmadığını döndürür. olan (

C++ operator precedence

operator overloading

std::basic_ostream::operator<<

std::basic_ios::operator bool

+0

, bu konuyla ilgili daha fazla bilgi veya bağlantı verebilir. – Zubair

+0

@Zubair: Bağlantılar eklendi. –

+0

Nitpick: Burada çalıştırılan “işleç <<” özel bir işlevdir [http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2]. –

13

std::cout<<"odd"std::cout döndürür ifadesidir:

fazla bilgi için aşağıdaki belgelere bakın neden std::cout << a << b << c yapabilirsin). Boolean bağlamında değerlendirildiğinde, başarısızlık biti ayarlanmamışsa, yalnızca doğru döner. Böylece çıkış işlemi başarılı olursa, o zaman doğru olarak değerlendirilecektir.

if (remainder & 1) { 
    std::cout << "odd"; 
} else { 
    std::cout << "even"; 
} 

Bu yararlanır:

Ancak, bu kodun amacı yerine, bu ifade etmek için bir akıllı (ve çok okunabilir olan) yöntemdir, bu değer test değildir && ve || operatörlerin kısa devre yapısı: a && b olarak

  • yanlıştır a ise o zaman(aolarak değerlendirilirdeğerlendirilmez!) aksi takdirde b olarak değerlendirir. a doğruysa aksi takdirde b olarak değerlendirir (b değerlendirilmez!) a olarak a || b yılında
  • , o zaman değerlendirir. && sentezleme kısa devre, yanlış geri çünkü

Böylece remainder & 1 (bu durumda sıfır) yanlış değerlendirildiğinde daha sonra std::cout << "odd" değerlendirilmez. Bu, b (std::cout << "even") değerine neden olan dışsal || ifadesinin sol işlenenidir, çıktıya "çift" yazılır.

remainder & 1 öğesi true olarak değerlendirilirse (bu durumda sıfır olmayan), && için sağ işlenen "odd" değerini görüntüleyerek değerlendirilir. Bu işlemin başarılı olduğunu varsayarsak, || işleminin sol işleneni doğru olur, bu da kısa devreye neden olur ve doğru işleneni değerlendirmez.


Deneyimli programcılar oluyor burada tam olarak bilmek muhtemeldir, ancak bulduk olarak bu tekniğin en okunabilir değildir. Kodun amacı hakkında basit olmak daha iyidir (IMO), bu yüzden bir if koşullu kullanıyorum - veya en azından üçlü operatörünü kullanıyorum: std::cout << (remainder & 1 ? "odd" : "even"). Diğer dillerde (JavaScript akla gelir) (ab) kısa devre kullanan operatörleri kullanarak çok yaygın bir tekniktir. Genelde C++ 'da bu şekilde kullandıklarını görmüyorum ve böyle bir kullanımdan vazgeçerim.

+0

Yalnızca derleyici boolean ifadesini kısa kenara bindirmeyi "std :: cout <<" tekdeyse "," kalan "ise" false "olarak değerlendirirse çalışır. Kısa devre olmaksızın, hem "cout <<" tek hem de "cout <<" bile "' büyük ihtimalle değerlendirilecektir. –

+6

@RemyLebeau Derleyici kısa bir süre içinde boolean uygulamıyorsa [uygun bir C++ derleyicisi değil] (http://stackoverflow.com/questions/628526/is-short-circuiting-boolean-operators-mandated-in -C = C-ve-değerlendirme dereceden). – cdhowie

+0

@cdhowie: açıklamanız daha değerli. – Zubair

İlgili konular