분명하고 평신도의 차이에 대한 설명 | 그리고 || C#에서?
-
22-08-2019 - |
문제
좋아, 나는 이것에 대해 여러 번 읽었지만 아직 다음의 차이점을 배울 수 있는 명확하고 이해하기 쉬운(그리고 기억에 남는) 방법을 듣지 못했습니다.
if (x | y)
그리고
if (x || y)
..C#의 맥락에서.누구든지 이 기본적인 사실과 C#이 이를 어떻게 다르게 취급하는지(같은 일을 하는 것처럼 보이기 때문에) 배울 수 있도록 도와주실 수 있나요?주어진 코드 조각 사이의 차이가 관련이 없는 경우 최선의 방법으로 기본적으로 무엇을 설정해야 합니까?
해결책
||
입니다 논리적 운영자. 보다 여기. 그것은 평가합니다 true
피연산자 중 하나 이상이 사실이라면. 부울 오페라에서만 사용할 수 있습니다. 정수 피연산자와 함께 사용하는 것은 오류입니다.
// Example
var one = true || bar(); // result is true; bar() is never called
var two = true | bar(); // result is true; bar() is always called
|
입니다 또는 운영자. 보다 여기. 부울 유형에 적용되면 평가합니다 true
피연산자 중 하나 이상이 사실이라면. 정수 유형에 적용되면 다른 숫자로 평가됩니다. 이 숫자는 피연산자 중 하나 이상에 해당 비트 세트가있는 경우 각 비트가 1으로 설정되어 있습니다.
// Example
var a = 0x10;
var b = 0x01;
var c = a | b; // 0x11 == 17
var d = a || b; // Compile error; can't apply || to integers
var e = 0x11 == c; // True
부울 피연산자의 경우, a || b
~이다 동일한 에게 a | b
, 단일 예외가 있습니다 b
다음과 같은 경우 평가되지 않습니다 a
사실이다. 이런 이유로 ||
"단락"이라고합니다.
주어진 코드가 그들 사이에있는 차이가 관련이 없다면, 어느 쪽이 가장 큰 행위로 기본적으로 기본적으로해야합니까?
언급 한 바와 같이, 그 차이는 관련이 없으므로이 질문은 부분적으로 무시됩니다. "모범 사례"는 하나가 없습니다. 일반적으로 사람들은 선호합니다 ||
~ 위에 |
부울 피연산자의 경우 불필요한 부작용을 일으키지 않을 수 있기 때문입니다.
다른 팁
부울 피연산자와 함께 사용될 때 |
연산자는 논리 연산자입니다 ||
, 그러나 차이점은 ||
연산자는 단락 평가를 수행합니다 |
운영자는 그렇지 않습니다.
이것은 두 번째 피연산자가 항상 |
연산자이지만 사용합니다 ||
연산자 두 번째 피연산자는 첫 번째 피연산자가 False로 평가되는 경우에만 평가됩니다.
표현의 결과는 항상 오페라 트로이 사람에게 항상 동일하지만, 두 번째 피연산자의 평가로 인해 다른 변화가 발생하면 사용하는 경우에만 보장됩니다. |
운영자.
예시:
int a = 0;
int b = 0;
bool x = (a == 0 || ++b != 0);
// here b is still 0, as the "++b != 0" operand was not evaluated
bool y = (a == 0 | ++b != 0);
// here b is 1, as the "++b != 0" operand was evaluated.
단락 평가 ||
두 번째 피연산자는 첫 번째 피연산자가 사실 인 경우에만 평가되므로 연산자는 더 짧은 코드를 작성하는 데 사용될 수 있습니다. 다음과 같이 쓰는 대신 :
if (str == null) {
Console.WriteLine("String has to be at least three characters.");
} else {
if (str.Length < 3) {
Console.WriteLine("String has to be at least three characters.");
} else{
Console.WriteLine(str);
}
}
다음과 같이 쓸 수 있습니다.
if (str == null || str.Length < 3) {
Console.WriteLine("String has to be at least three characters.");
} else{
Console.WriteLine(str);
}
두 번째 피연산자는 첫 번째가 false 인 경우에만 평가되므로 두 번째 피연산자가 평가되면 무효가 될 수 없으므로 두 번째 피연산자에서 문자열 참조를 안전하게 사용할 수 있음을 알고 있습니다.
대부분의 경우 사용하려고합니다 ||
연산자보다는 |
운영자. 첫 번째 피연산자가 False 인 경우 결과를 얻기 위해 두 번째 피연산자를 평가할 필요가 없습니다. 또한, 많은 사람들 (분명히)은 당신이 사용할 수 있다는 것을 알지 못합니다. |
부울 피연산자를 사용한 운영자이므로 코드에서 그런 식으로 사용되는 것을 볼 때 혼란스러워집니다.
그들은 동일하지 않습니다. 하나는 조금이거나 하나는 논리적이거나.
x || y는 논리적이거나 "x 또는 y"와 동일하며 BOOL 값에 적용됩니다. 조건부 또는 테스트에 사용됩니다. 이 경우 x와 y는 bool로 평가하는 모든 표현으로 대체 될 수 있습니다. 예시:
if (File.Exists("List.txt") || x > y ) { ..}
두 조건 중 하나가 참이면 조항은 참으로 평가됩니다. 첫 번째 조건이 true 인 경우 (파일이 존재하는 경우) 두 번째 조건은 평가할 필요가 없으며 평가되지 않습니다.
단일 파이프 (|)는 약간 또는. 이것이 무엇을 의미하는지 아는 것은 컴퓨터에 숫자가 어떻게 저장되는지 이해해야합니다. 값 15를 보유하는 16 비트 수량 (int16)이 있다고 가정 해보십시오. 실제로 바이너리에서 0000 0000 0000 1111과 동일한 0x000F (16 진)로 저장됩니다. 비트 또는 두 가지 수량 및 OR의 각 쌍의 해당 비트 쌍을 함께 사용하므로 비트가 양이 1 인 경우 결과에서 1입니다. 따라서 a = 0101 0101 0101 0101 (16 진수에서 0x5555로 평가) 및 b = 1010 1010 10101010 (0xaaaa)이면 a | B = 1111 1111111111 = 0xffff.
C#에서 Bitwise OR (단일 파이프)을 사용하여 하나 이상의 특정 비트 세트가 켜져 있는지 테스트 할 수 있습니다. 테스트 할 12 개의 부울 또는 이진 값이있는 경우 이렇게 할 수 있으며 모두 독립적입니다. 학생 데이터베이스가 있다고 가정합니다. 일련의 독립 부울은 남성/여성, 가정/캠퍼스, 현재/전류, 등록/등록 등과 같은 것들 일 수 있습니다. 해당 값에 대한 부울 필드를 저장하는 대신 저장할 수 있습니다. 각각에 대해 조금만. 남성/여성은 조금 일 수 있습니다. 등록/비트 2 일 수 있습니다.
그런 다음 사용할 수 있습니다
if ((bitfield | 0x0001) == 0x0001) { ... }
"학생은 남성"비트를 제외하고 비트가 켜지지 않는지 확인하는 테스트로 무시됩니다. 뭐? 글쎄, 비트 와이드 또는 1 숫자에 따라 각 비트마다 1을 반환합니다. 비트 이상의 결과가 = 0x0001의 결과 인 경우, 비트 필드에는 비트가 켜지지 않음을 의미합니다. 아마도 첫 번째 비트 (0x0001)이지만 첫 번째 비트가 켜져 있는지 확인할 수는 없습니다.
해당 && 및 &는 논리적이고 비트와 관련이 있습니다. 그들은 유사한 행동을 가지고 있습니다.
당신이 사용할 수있는
if ((bitfield & 0x0001) == 0x0001) { ... }
첫 번째 비트가 비트 필드에서 켜져 있는지 확인합니다.
편집 : 나는 이것을 위해 투표를 받았다고 믿을 수 없다!
좋은 답변이지만 오른쪽 표현을 추가하겠습니다. ||
왼쪽 표현이 있는지 여부는 평가되지 않습니다 true
. 평가 용어가 a) 성능 집약적 인 경우 또는 b) 부작용 (희귀)을 생성하는 경우이를 명심하십시오.
지금까지 대부분의 답변과 달리 의미는 ~ 아니다 C ++에서 정확히 동일합니다.
부울에 대한 두 가지 표현 A와 B의 경우 a || B와 A | B는 거의 똑같은 일을합니다.
A | B를 평가합니다 둘 다 A와 B, 그리고 그들 중 하나가 True로 평가되면 결과는 사실입니다.
A || B는 첫 번째를 평가 한 다음 필요한 경우 B 만 평가합니다. A 또는 B 중 하나가 참이면 전체 표현식이 참이므로 A가 참이면 B를 전혀 테스트 할 필요가 없습니다. 그래서 || 짧은 회로, 그리고 가능한 경우 두 번째 피연산자를 평가하는 건너 뛰기, 여기서 | 운영자는 항상 두 가지를 모두 평가합니다.
| 운영자는 종종 사용되지 않으며 종종 차이를 만들지 않습니다. 내가 어디에서 차이가 있을지 생각할 수있는 유일한 일반적인 사례는 다음과 같습니다.
if ( foo != null || foo.DoStuff()){ // assuming DoStuff() returns a bool
}
왼쪽 테스트가 실패하면 dostuff () 멤버 함수가 호출되지 않기 때문에 작동합니다. 즉, Foo가 Null이면 Dostuff를 부르지 않습니다. (우리에게 nullReferenceException을 줄 것입니다).
우리가 | 연산자, dostuff ()는 foo가 null인지 아닌지에 관계없이 호출됩니다.
정수에서만 | 연산자는 정의되며, 다른 답변이 설명대로 약간 또는 약간입니다. || 오퍼레이터는 정수 유형에 대해 정의되지 않았으므로 C#에서 혼합하기가 어렵습니다.
| 비트 또는 연산자 (숫자, 정수)입니다. 숫자를 이진으로 변환하고 해당 숫자 각각에 대해 또는 수행하여 작동합니다. 그런 다음 숫자는 이미 컴퓨터의 바이너리로 표시되므로 런타임에 실제로 이러한 변환은 발생하지 않습니다.)
|| 논리적 또는 연산자 (부울)입니다. 그것은 참와 거짓 값에만 작동합니다.
다음은 부울에 대한 일류 지원이 없기 때문에 C/C ++에서 작동합니다. 모든 표현식을 "ON ON"비트로 처리합니다. 실제로 x와 y가 숫자 유형 인 경우 다음 코드는 C# 또는 Java에서 작동하지 않습니다.
if (x | y)
따라서 위의 코드의 명시 적 버전은 다음과 같습니다.
if ( (x | y) != 0)
C에서 "on"비트를 갖는 모든 표현, true에 대한 결과
int i = 8;
if (i) // c에서 유효한 경우, true에 대한 결과
int Joy = -10;
if (Joy) // c에서 vaild, true에 대한 결과
이제 C#로 돌아 가기
x와 y가 숫자 유형 인 경우 코드입니다. if (x | y) 작동 안 할 것이다. 컴파일을 시도해 보셨습니까? 이거 작동 안 할거야
그러나 코드의 경우 X와 Y가 부울 유형이라고 가정 할 수 있으므로 작동하므로 | 그리고 || 부울 유형의 경우 || 짧은 순회, | 아니다. 다음의 출력 :
static void Main()
{
if (x | y)
Console.WriteLine("Get");
Console.WriteLine("Yes");
if (x || y)
Console.WriteLine("Back");
Console.ReadLine();
}
static bool x
{
get { Console.Write("Hey"); return true; }
}
static bool y
{
get { Console.Write("Jude"); return false; }
}
이다:
HeyJudeGet
Yes
HeyBack
Jude는 두 번 인쇄되지 않습니다. || 부울 연산자이며 많은 C 파생 언어 부울 운영자가 단락, 부울 표현은 단락 된 경우 더 성능이 있습니다.
평신도 용어에 관해서는, 예를 들어 ||에서 단락을 말할 때. (또는 연산자), 첫 번째 표현식이 이미 사실 인 경우 두 번째 표현식을 평가할 필요가 없습니다. 예 : if (ask == 'y'|| answer == 'y'), 사용자가 small y를 누르면 프로그램이 두 번째 표현식을 평가할 필요가 없습니다 (답 == 'y'). 그것은 단락입니다.
위의 샘플 코드에서 x는 true이므로 y on || 연산자는 더 이상 평가되지 않으므로 두 번째 "Jude"출력은 없습니다.
x와 y가 부울 유형 인 경우에도 C#에서 이러한 종류의 코드를 사용하지 마십시오. if (x | y). 수행되지 않습니다.
첫 번째 비트 연산자는 두 개의 숫자 값에 대해 작동하여 세 번째 값을 생성합니다.
바이너리 변수가 있는 경우
a = 0001001b;
b = 1000010b;
그 다음에
a | b == 1001011b;
즉, 결과의 비트는 피연산자 중 하나에서도 1인 경우 1입니다.(내 예에서는 명확성을 위해 8비트 숫자를 사용합니다.)
"이중 파이프" ||는 두 개의 부울 값을 사용하여 세 번째 결과를 얻는 논리적 OR 연산자입니다.
어떤 식 으로든 세부 사항, 모양 또는 형태를 탐구하지 않고 다음은 다음과 같습니다. 진짜 평신도의 버전.
"|"를 생각하십시오 똑바로 "또는"영어로; "||"를 생각하십시오 영어로 "또는 else"로.
마찬가지로 "&"As "및"영어로 생각하십시오. "&&"는 "As"와 영어로 생각하십시오.
이 용어를 사용하여 자신에게 표현을 읽으면 종종 훨씬 더 의미가 있습니다.
읽어 보는 것이 좋습니다 이것 Dotnet Mob의 기사
오페라 중 하나라도 진실로 평가되면 전체 표현식이 True로 평가됩니다.
이것이 || 운영자는 - 사실을 발견했을 때 나머지 평가를 건너 뜁니다. 동안 | 연산자는 전체 표현의 가치를 분석하기위한 완전한 피연산자임을 평가합니다.
if(true||Condition1())//it skip Condition1()'s evaluation
{
//code inside will be executed
}
if(true|Condition1())//evaluates Condition1(), but actually no need for that
{
//code inside will be executed
}
또는 (||) 또는 (&&) 연산자이든 논리 연산자의 단락 버전을 사용하는 것이 좋습니다.
다음 코드 스 니펫을 고려하십시오
int i=0;
if(false||(++i<10))//Now i=1
{
//Some Operations
}
if(true||(++i<10))//i remains same, ie 1
{}
이 효과를 호출합니다 부작용, 실제로 단락 논리 연산자에서 표현식의 오른쪽에서 볼 수 있습니다.
참조 : C#의 단락 평가
이미 말하고 올바르게 대답했지만이 사이트에서 내가 느끼는 시간 이후로 실제 평신도의 대답을 추가 할 것이라고 생각했습니다. :). 게다가 & vs. &&의 예를 추가하겠습니다.
| vs ||
기본적으로 당신은 ||를 사용하는 경향이 있습니다 첫 번째 부분이 허위 인 경우 두 번째 부분을 평가하기 만하면됩니다. 그래서 이거:
if (func1() || func2()) {func3();}
와 같다
if (func1())
{
func3();
}
else
{
if (func2()) {func3();}
}
이것은 처리 시간을 절약하는 방법 일 수 있습니다. func2 ()가 처리하는 데 오랜 시간이 걸렸다면 func1 ()가 이미 사실이라면 그렇게하고 싶지 않을 것입니다.
& vs &&
& vs. &&의 경우 첫 번째 부분이 사실 인 경우 두 번째 부분 만 평가하는 비슷한 상황입니다. 예를 들어 이것은 :
if (func1() && func2()) {func3();}
와 같다
if (func1())
{
if (func2()) {func3();}}
}
func2 ()가 func1 ()에 의존 할 수 있으므로 먼저 필요할 수 있습니다. 당신이 & 및 func1 ()을 사용하는 경우 false로 평가 한 경우, 어쨌든 func2 ()를 실행하여 런타임 오류가 발생할 수 있습니다.
평신도 제프