हरण - PHP में & && के बीच अंतर




php कोडिंग उदाहरण (4)

मैं && उलझन में हूं। मेरे पास दो PHP किताबें हैं। एक कहता है कि वे समान हैं, लेकिन दूसरा कहता है कि वे अलग हैं। मुझे लगा कि वे भी वैसे ही हैं।

क्या वे समान नहीं हैं?


अन्य उत्तर सही हैं, लेकिन अधूरे हैं। तार्किक और की एक प्रमुख विशेषता यह है कि यह शॉर्ट-सर्किट है, जिसका अर्थ है कि यदि आवश्यक हो तो केवल दूसरे ऑपरेंड का मूल्यांकन किया जाता है। PHP मैनुअल निम्नलिखित उदाहरण देता है:

$a = (false && foo());

foo को कभी भी नहीं बुलाया जाएगा, क्योंकि परिणाम का मूल्यांकन गलत के मूल्यांकन के बाद किया जाता है। दूसरी ओर के साथ

$a = (false & foo());

foo कहा जाएगा (भी, परिणाम 0 के बजाय गलत है)।


जैसा कि अन्य कह रहे हैं, एक एकल & बिट-बुद्धिमान है। यह मूल रूप से बाएं हाथ के मूल्य को अपने बिट्स प्रतिनिधित्व में परिवर्तित करता है, और दाहिने हाथ की तरफ बिट्स प्रतिनिधित्व में, फिर तार्किक और उनके बीच प्रदर्शन करता है और परिणाम को आउटपुट करता है।

डबल && या तो सही है या गलत है, (कुछ भाषाओं में 0 या 1) यदि बाईं और दाईं दोनों साइड सच्ची (या गैर-शून्य) हैं।

मैं यह भी जोड़ूंगा कि यह सिर्फ PHP में नहीं है। यह कई अन्य भाषाओं के साथ-साथ सी, जावा, Ruby , आदि में भी ऐसा ही है।



तार्किक और && संचालक के बारे में मैथ्यू का जवाब सबसे बड़ा अंतर है; तार्किक तुलना बंद हो जाएगी जब यह कुछ ऐसा पाएगा जो श्रृंखला को तोड़ता है। इसके अलावा, एक और बड़ा अंतर यह परिणाम प्रकार / मूल्य है

tl; डॉ

तार्किक और && का उपयोग करके, यह हमेशा एक बूलियन प्रकार / मान लौटाएगा, true या false

false & 1 // int(0)
false && 1 // bool(false)

तार्किक परिणाम के साथ फ़ंक्शन वापस करते समय बुलियन प्रकार / मूल्यों का उपयोग करना महत्वपूर्ण है, क्योंकि कोई व्यक्ति परिणाम की तुलना करने के लिए आइडेंटिकल तुलना ऑपरेटर === का उपयोग कर सकता है (जो होने की संभावना अधिक है) और यह विफल हो जाएगा यदि आप कुछ का उपयोग करते हैं जैसे इस:

(false & 1) === false // bool(false)
(true & true) === true // bool(false)

कभी भी Bitwise और & उपयोग न करें जब आपको तार्किक तुलना करने की आवश्यकता होती है और विशेष रूप से जब तार्किक परिणामों के साथ फ़ंक्शन से मान लौटाते हैं। इसके बजाय तार्किक और && उपयोग करें:

(false && 1) === false // bool(true)
(true && true) === true // bool(true)

वर्णों की तुलना करते समय, तार्किक और && NUL चरित्र के साथ भी हमेशा true होगा, जब तक कि यह पूर्णांक में परिवर्तित न हो जाए:

'A' && 'B' // bool(true)
'A' && 0 // bool(false)
'A' && '\0' // bool(true)
'A' && (int)'\0' // bool(false)

यदि आप बिटवाइज़ और & वर्णों का उपयोग करते हैं, तो यह उन दो वर्णों के बीच बिटवाइज़ और ऑपरेशन के अनुरूप वर्ण का परिणाम देगा:

'A' & 'B' // string(1) "@"

01000001 // ASCII 'A'
&
01000010 // ASCII 'B'
=
01000000 // ASCII '@'

बिटवाइज और & के उपयोग से सावधान रहें जब इंटेगर और कैरेक्टर (जो विशेष प्रकार के पूर्णांक हैं) के अलावा अन्य प्रकारों का उपयोग करते हैं। उदाहरण के लिए, यदि आप इसका उपयोग वास्तविक संख्या फ्लोट / डबल के साथ करते हैं , तो इसका परिणाम 0 हो सकता है, भले ही दोनों ऑपरेंड न हों :

1.0 & 1.0 // int(1)
2.0 & 1.0 // int(0)

1.0 && 1.0 // bool(true)
2.0 && 1.0 // bool(true)

इसके अलावा, अगर हम विधानसभा निर्देश स्तर पर जाते हैं, तो हम उस अंतर को देख सकते हैं और संकलक कैसे संभालता है इसलिए लॉजिकल एंड && cmp <var>, 0 का उपयोग करता है cmp <var>, 0 की तुलना करने के लिए और निष्पादित नहीं करता है अगर एक ऑपरेंड विफल रहता है; बिटवाइज़ और उपयोग करता है and <var1>, <var2> एक बिटवाइज़ परिणाम बनाने के लिए और फिर 0 मान होने पर परीक्षण करें। मुझे पता है कि यह सवाल php लिए टैग किया गया है और php व्यवहार c से भिन्न हो सकता है, लेकिन मैं लॉजिकल और बिटवाइज़ का उपयोग करते समय कंपाइलर कैसे व्यवहार करता है, यह प्रदर्शित करने के लिए एक छोटे c प्रोग्राम का उपयोग करूँगा।

मान लेते हैं कि हमारे पास c में एक प्रोग्राम है जो बिटवाइज़ और लॉजिकल और दोनों का उपयोग करता है:

int a = 0;
int b = 1;
int c = 2;

if (a & b)
    c = 3;

if (a && b)
    c = 4;

कंपाइलर निम्नलिखित असेंबली ऑपकोड उत्पन्न करेगा ( x86 के लिए W32Dasm परिणाम ; मैंने मेमोरी पतों को <variable> सरलता के लिए नाम और अधिक समझने योग्य होने के लिए) बदल दिया है:

:0229  mov <a>, 0
:0230  mov <b>, 1
:0237  mov <c>, 2
// if (a & b) begins
:023E  mov eax, <a>
:0241  and eax, <b>        // a bitwise and b, result stored to eax
:0244  test eax, eax       // test eax and set ZeroFlag if equals to 0
:0246  je 024F             // >---  Jump if ZeroFlag is set
:0248  mov <c>, 3          //    |  or set c = 3
// if (a && b) begins            |
:024F  cmp <a>, 0          // <---  compare a to 0 and sets ZeroFlag if difference is 0
:0253  je 0262             // >---  Jump if ZeroFlag is set (a == 0)
:0255  cmp <b>, 0          //    |  compare b to 0 and sets ZeroFlag if differemce is 0
:0259  je 0262             //    |  >--- Jump if ZeroFlag is set (b == 0)
:025B  mov <c>, 4          //    |     | or set c = 4
:0262  <program continues> // <---  <---

संकलक न केवल तार्किक और बिटवाइस और के बीच तुलना करने के लिए विभिन्न निर्देशों का उपयोग करता है, लेकिन पंक्ति में :0253 if (a && b) तार्किक तुलना में, हम देखते हैं कि यदि a == 0 तो यह कूदता है और बाकी की जांच नहीं करता है ऑपरेंड।

इसलिए, मैं एनिमसन की टिप्पणी से असहमत हूं:

वे दोनों एक ही काम कर रहे हैं, वे एक ही कार्य को पूरा करने के लिए दो अलग-अलग चीजों के लिए उपयोग किए जाते हैं। - 1 मई को 1:42 पर एनिमूसन 4 '10

वे समान चीज़ नहीं हैं और दोनों ही कार्यक्रमों के तर्क / प्रवाह के आधार पर विशिष्ट कार्यों के लिए उपयोग किए जाने वाले / (होने चाहिए) हैं





php