ProgramlamaC programcısı

C dilinde mantıksal VE (&&) ve VEYA (||) operatörlerinin nasıl çalıştığını anlatın. Kısa devre değerlendirmesi (short-circuit evaluation) olarak adlandırılan özelliğin farkları nelerdir? Bu operatörlerin davranışını yanlış anlamanın hatalara nasıl yol açabileceğini açıklayın.

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Soru geçmişi:

C dilinde karmaşık mantıksal koşulları kontrol etmek için && ve || mantıksal operatörleri tanıtıldı. Bu operatörlerin çalışma özelliği, ikinci operandın, sonuç birinci operand üzerinden kesin olarak belirlenebiliyorsa hesaplanmamasıdır.

Sorun:

Birçok programcı, her iki operandın her zaman hesaplanacağını bekler veya ikinci operandın yan etkilerini yanlış kullanarak mutlaka çalışacağını varsayar. Bu durum pratikte hatalara, kaynak sızıntılarına ve beklenmedik davranışlara yol açar.

Çözüm:

Kısa devre değerlendirmesi mekanizmasını anlamak, özellikle işaretçi, kaynak ve dosya kontrollerinde güvenli yapılar inşa etmeye yardımcı olur. İfade sağ tarafında yan etkilerin kullanılmasını yalnızca bilinçli bir şekilde yapmak gerekir. Güvenli bir kontrol örneği:

if (ptr && ptr->field) { /* ... */ }

Ana özellikler:

  • && ve || 'kısa devre' kuralını kullanır — ikinci operand yalnızca ilk operandın sonucu belirlenmediğinde hesaplanır.
  • Kısa devre, null işaretçilerine erişimi, sıfıra bölmeyi ve diğer tehlikeli durumları önlemeye yardımcı olur.
  • Yan etkilere sahip ifadelerin yer içlerinde yer alması durumunda, sağ tarafın hiç çalışmayabileceği durumlarda hatalar ortaya çıkar.

Kandırmaca soruları.

if (0 && f()) bölümünde f() ifadesi çalışacak mı?

Hayır, f() fonksiyonu çağrılmayacak çünkü sonuç zaten belirsiz — ifade yanlış, daha fazla hesaplama gereksiz.

Peki, şu yazımda: if (1 || f())?

Yine f() çağrılmayacak: sonuç birinci operand sonrası zaten doğru.

Yan etkileri olan fonksiyonların çağırılma sırasını kontrol etmek için && ve || operatörlerini kullanmak mümkün mü?

Teknik olarak mümkündür ama bu tür bir kontrol okunaksız ve kararsız koda yol açar. Fonksiyonların çağrılma sırasını açık bir şekilde belirtmek daha iyidir, yan etkiler için kısa devre davranışına güvenmemek gerekir.

Yaygın hatalar ve anti-desenler

  • Sağ taraftaki ifadelerde yan etkileri kullanarak mutlaka çalışacaklarını ummak.
  • Bir işaretçiyi derecelendirmeden önce NULL kontrolü yapmama.
  • Hesaplama sırasını anlamayı zorlaştıran karmaşık iç içe koşullar.

Gerçek yaşam örneği

Olumsuz durum

if (flag || process()) { // ... }

Eğer flag doğruysa, işlem asla çağrılmayacaktır.

Artılar:

  • Gereksiz işlerden korunma var.

Eksiler:

  • Yan etkiler beklendiği zaman gerçekleşmez, bir hata ortaya çıkar.

Olumlu durum

if (!flag) process();

Artılar:

  • Okunabilir, güvenli ve öngörülebilir kod.

Eksiler:

  • Biraz daha fazla satır, daha açık bir kontrol gerektirir ama okunabilirlik ve öngörülebilirlik artar.