문제

C#에서(다른 언어에 대해서는 자유롭게 대답하세요) 런타임은 논리문을 어떤 순서로 평가합니까?

예:

DataTable myDt = new DataTable();
if (myDt != null && myDt.Rows.Count > 0)
{
    //do some stuff with myDt
}

런타임은 어떤 명령문을 먼저 평가합니까?

myDt != null

또는:

myDt.Rows.Count > 0

?

컴파일러가 명령문을 거꾸로 평가할 때가 있습니까?아마도 "OR" 연산자가 포함된 경우일까요?


&는 논리적 비트 연산자로 알려져 있으며 항상 모든 하위 표현식을 평가합니다.

"단락 부울" 대신 비트 연산자를 사용하는 좋은 예는 무엇입니까?

도움이 되었습니까?

해결책

씨# :왼쪽에서 오른쪽으로, 일치하지 않는 항목(거짓으로 평가됨)이 발견되면 처리가 중지됩니다.

다른 팁

"씨# :왼쪽에서 오른쪽으로, 일치하는 항목(true로 평가됨)이 발견되면 처리가 중지됩니다."

좀비 양은 틀렸습니다. 반대표를 던질 만큼 충분한 대표자가 없습니다.

문제는 ||가 아니라 && 운영자에 관한 것입니다. 운영자.

&&의 경우 FALSE가 발견되면 평가가 중지됩니다.

||의 경우 진실이 발견되면 평가가 중지됩니다.

이 질문에 이미 답변이 있었음을 알고 있지만 해당 주제와 관련된 또 다른 정보를 추가하고 싶습니다.

C ++와 같은 언어에서 실제로 && 및 ||의 동작을 과부하시킬 수 있습니다. 운영자, 당신을 적극 권장합니다 이러지 마.이는 이 동작에 과부하가 걸리면 결국 작업의 양쪽 측면을 강제로 평가하게 되기 때문입니다.이는 두 가지 작업을 수행합니다.

  1. 오버로드는 호출되어야 하는 함수이고 따라서 함수를 호출하기 전에 두 매개변수가 모두 평가되기 때문에 이는 지연 평가 메커니즘을 깨뜨립니다.
  2. 해당 매개변수의 평가 순서는 보장되지 않으며 컴파일러에 따라 다를 수 있습니다.따라서 객체는 질문/이전 답변에 나열된 예와 동일한 방식으로 동작하지 않습니다.

더 많은 정보를 원하시면 Scott Meyers의 책을 읽어보세요. 더욱 효과적인 C++.건배!

vb.net

if( x isNot Nothing AndAlso x.go()) then
  1. 평가는 왼쪽에서 오른쪽으로 이루어집니다.
  2. 그리고 또한 연산자는 왼쪽이 TRUE인 경우에만 오른쪽이 평가되도록 합니다(매우 중요합니다. ifx가 아무것도 아니기 때문에 x.go가 충돌할 것입니다)

당신은 사용할 수 있습니다 그리고 vb에서는 ofAndAlso 대신.이 경우 왼쪽도 먼저 평가되지만 결과에 관계없이 오른쪽이 평가됩니다.

모범 사례:그렇게 하지 말아야 할 타당한 이유가 없는 한 항상 AndAlso를 사용하십시오.


후속 조치에서는 AndAlso(또는 && 대신 &) 대신 And를 사용하는 이유와 시기를 묻는 질문이 있었습니다.예는 다음과 같습니다.

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

이 경우 X와 Y를 모두 초기화하고 싶습니다.y.DoDance를 실행할 수 있으려면 Y를 초기화해야 합니다.그러나 init() 함수에서는 소켓이 열려 있는지 확인하는 것과 같은 추가 작업도 수행하고 있으며, 이것이 제대로 작동하는 경우에만 가능합니다. 둘 다, 계속해서 x.process(y)를 수행해야 합니다.

다시 말하지만, 이는 아마도 필요하지 않으며 99%의 경우 우아하지도 않습니다. 그래서 기본값은 다음을 사용해야 한다고 말한 것입니다. 그리고 또한.

@shsteimer

겸손이 말하는 개념은 연산자 과부하입니다.성명서에서 :...A가 먼저 평가되고, false로 평가되면 B는 평가되지 않습니다.동일하게 적용됩니다

그것은 연산자 과부하가 아닙니다.연산자 오버로딩은 *, +, = 등과 같은 연산자에 대한 사용자 정의 동작을 정의할 수 있도록 하는 용어입니다.

이렇게 하면 자신만의 'Log' 클래스를 작성하고 다음을 수행할 수 있습니다.

a = new Log(); // Log class overloads the + operator
a + "some string"; // Call the overloaded method - otherwise this wouldn't work because you can't normally add strings to objects.

이것을 하면서

a() || b() // be never runs if a is true

실제로 호출됩니다 단락 평가

ZombieSheep이 죽었습니다.기다리고 있을 수 있는 유일한 "문제"는 이것이 && 연산자를 사용하는 경우에만 해당된다는 것입니다.& 연산자를 사용하면 둘 중 하나 또는 둘 다 false로 평가되는지 여부에 관계없이 두 표현식이 매번 평가됩니다.

if (amHungry & whiteCastleIsNearby)
{
   // The code will check if White Castle is nearby
   // even when I am not hungry
}

if (amHungry && whiteCastleIsNearby)
{
   // The code will only check if White Castle is nearby
   // when I am hungry
}

표현의 평가 정도와 관련하여 &&와 & 사이에는 차이가 있습니다.

&&는 단락 부울 AND로 알려져 있으며 여기에서 다른 사람들이 언급한 것처럼 모든 하위 표현식이 평가되기 전에 결과가 결정될 수 있으면 일찍 중지됩니다.

&는 논리적 비트 연산자로 알려져 있으며 항상 모든 하위 표현식을 평가합니다.

따라서:

if (a() && b())

전화만 할게 만약에 보고 진실.

그러나 이것은:

if (a() & b())

항상 둘 다 호출합니다. 그리고 , 호출 결과에도 불구하고 거짓이므로 다음과 같이 알려져 있습니다. 거짓 호출 결과와 상관없이 .

||에 대해서도 동일한 차이가 있습니다 그리고 | 운영자.

일부 언어에는 표현식이 다른 순서로 실행되는 흥미로운 상황이 있습니다.나는 특히 Ruby를 생각하고 있지만 다른 곳(아마 Perl)에서 빌린 것이라고 확신합니다.

논리 표현식은 왼쪽에서 오른쪽으로 유지되지만 예를 들면 다음과 같습니다.

puts message unless message.nil?

위의 내용은 "Message.nil?"를 평가할 것입니다. 먼저, false로 평가되면 (조건이 true 대신 false 일 때 실행되는 경우를 제외하고는 그렇지 않은 한), "메시지 변수의 내용을 화면에 인쇄하는"메시지를 넣습니다.

때로는 코드를 구성하는 흥미로운 방법입니다.저는 개인적으로 위와 같이 매우 짧은 1라이너에 사용하는 것을 좋아합니다.

편집하다:

좀 더 명확하게 하기 위해 위의 내용은 다음과 같습니다.

unless message.nil?
  puts message
end

왼쪽은 null이면 중지됩니다.

편집하다:vb.net에서는 AndAlso를 사용하지 않는 한 두 가지를 모두 평가하여 오류가 발생할 수 있습니다.

겸손이 말하는 개념은 연산자 과부하입니다.성명서에서 :

if( A && B){
    // do something
}

A가 먼저 평가되고, false로 평가되면 B는 평가되지 않습니다.동일하게 적용됩니다

if(A || B){
    //do something
}

A가 먼저 평가되고, true로 평가되면 B는 평가되지 않습니다.

오버로딩이라는 이 개념은 모든 C 스타일 언어와 다른 많은 언어에도 적용됩니다.

아니요, 적어도 C# 컴파일러는 역방향(&& 또는 ||)으로 작동하지 않습니다.왼쪽에서 오른쪽입니다.

모든 것이 인라인으로 정렬되면 왼쪽에서 오른쪽으로 실행됩니다.

중첩되면 내부에서 외부로 실행됩니다.일반적으로 "가장 안쪽"이 선의 오른쪽에 있기 때문에 혼란스러워 보일 수 있습니다. 그래서 뒤로 가는 것처럼 보입니다.

예를 들어

a = Foo( 5, GetSummary( "Orion", GetAddress("Orion") ) );

상황은 다음과 같이 발생합니다.

  • 부르다 GetAddress 문자 그대로 "Orion"
  • 부르다 GetSummary 문자 그대로 "Orion" 그리고 그 결과 GetAddress
  • 부르다 Foo 문자 그대로 5 그리고 그 결과 GetSummary
  • 이 값을 다음에 할당합니다. a

저는 오리온의 반응을 좋아합니다.두 가지를 추가하겠습니다.

  1. 여전히 왼쪽에서 오른쪽이 먼저 적용됩니다.
  2. 함수를 호출하기 전에 모든 인수가 해결되도록 내부에서 외부로

다음과 같은 예가 있다고 가정해 보겠습니다.

a = Foo(5, GetSummary("Orion", GetAddress("Orion")),
           GetSummary("Chris", GetAddress("Chris")));

실행 순서는 다음과 같습니다.

  1. GetAddress("Orion")
  2. GetSummary("Orion", ...)
  3. GetAddress("Chris")
  4. GetSummary("Chris", ...)
  5. Foo(...)
  6. 할당 대상 a

C#의 법적 요구 사항에 대해서는 말할 수 없지만(이 게시물을 작성하기 전에 Mono를 사용하여 비슷한 예제를 테스트했지만) 이 순서는 Java에서 보장됩니다.

그리고 완벽함을 위해(이 역시 언어에 구애받지 않는 스레드이기 때문에) 시퀀스 포인트가 없으면 순서가 보장되지 않는 C 및 C++와 같은 언어가 있습니다.참고자료: 1, 2.그러나 스레드의 질문에 대답하면서, && 그리고 || C++의 시퀀스 포인트입니다(오버로드되지 않는 한;OJ의 훌륭한 답변도 참조하세요).몇 가지 예는 다음과 같습니다.

  • foo() && bar()
  • foo() & bar()

에서 && 사례, foo() 전에 실행이 보장됩니다 bar() (후자가 전혀 실행되는 경우), 이후 && 시퀀스 포인트입니다.에서 & 경우에는 그러한 보장이 이루어지지 않으며(C 및 C++에서는) 실제로 bar() 전에 실행할 수 있습니다 foo(), 혹은 그 반대로도.

"단락 부울" 대신 비트 연산자를 사용하는 좋은 예는 무엇입니까?

파일 속성과 같은 플래그가 있다고 가정해 보겠습니다.READ를 4로, WRITE를 2로, EXEC를 1로 정의했다고 가정해 보겠습니다.바이너리에서는 다음과 같습니다.

READ  0100  
WRITE 0010  
EXEC  0001

각 플래그에는 하나의 비트 세트가 있으며 각 플래그는 고유합니다.비트 연산자를 사용하면 다음 플래그를 결합할 수 있습니다.

flags = READ & EXEC; // value of flags is 0101

컴파일러가 역방향으로 작동한다는 말을 어딘가에서 들었지만 이것이 얼마나 사실인지는 확실하지 않습니다.

모든 하위 표현식을 구체적으로 평가하고 싶을 때 &를 사용합니다. 최종 결과가 거짓 따라서 실행하지 마십시오 그 다음에 당신의 일부 만약에-성명.

& | Bitwise Masks와 Boolean 값 모두에서 작동하며 Bitwise 작업만을위한 것이 아닙니다.그들은 ~라고 불리는 비트 단위이지만 C#에서는 정수 및 부울 데이터 형식 모두에 대해 정의됩니다.

@csmba:

후속 조치에서는 AndAlso(또는 && 대신 &) 대신 And를 사용하는 이유와 시기를 묻는 질문이 있었습니다.예는 다음과 같습니다.

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

이 경우 X와 Y를 모두 초기화하고 싶습니다.y.DoDance를 실행할 수 있으려면 Y를 초기화해야 합니다.그러나 init() 함수에서는 소켓이 열려 있는지 확인하는 것과 같은 추가 작업도 수행하고 있으며, 문제가 없을 경우에만 두 가지 모두 x.process(y)를 수행해야 합니다.

나는 이것이 다소 혼란스럽다고 생각한다.귀하의 예제는 작동하지만 다음을 사용하는 일반적인 경우는 아닙니다. And (그리고 아마도 더 명확하게 하기 위해 이것을 다르게 쓸 것입니다). And (& 대부분의 다른 언어에서는) 실제로 비트 AND 연산입니다.이를 사용하여 플래그 비트 삭제 또는 플래그 마스킹 및 테스트와 같은 비트 작업을 계산할 수 있습니다.

Dim x As Formatting = Formatting.Bold Or Formatting.Italic
If (x And Formatting.Italic) = Formatting.Italic Then
    MsgBox("The text will be set in italic.")
End If

D 프로그래밍 언어가 하는 일 단락을 사용한 왼쪽에서 오른쪽 평가 그리고 그렇지 않다 과부하를 허용 && 그리고 '||' 연산자.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top