참 조건(x = x ?: 1)에 대한 값을 할당하지 않고 3진수 연산자를 사용하는 이유는 무엇입니까?
안드로이드 오픈 소스 qemu 코드에서 나는 다음 코드 라인을 가로질러 실행했습니다.
machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
이것은 단지 다음과 같이 말하는 혼란스러운 방식입니까?
if (machine->max_cpus) {
; //do nothing
} else {
machine->max_cpus = 1;
}
그렇다면 다음과 같이 더 명확하지 않을까요?
if (machine->max_cpus == 0) machine->max_cpus = 1;
흥미롭게도, 이것은 gcc와 잘 컴파일되고 작동하지만, http://www.comeaucomputing.com/tryitout/ 에서는 컴파일되지 않습니다.
이는 GNU에서 C에 대한 모호한 확장으로 허용됩니다.
5.7 피연산자가 누락된 조건
조건식의 중간 피연산자는 생략될 수 있습니다.그런 다음 첫 번째 피연산자가 0이 아닌 경우 해당 값은 조건식의 값입니다.
그러므로, 그 표현은
x ? : y
0이 아닐 경우 x의 값을 가지며, 그렇지 않을 경우 y의 값을 가집니다.
이 예는 완전히 다음과 같습니다.
x ? x : y
이 간단한 경우 중간 피연산자를 생략하는 기능은 특별히 유용하지 않습니다.첫 번째 피연산자가 사용하거나 (매크로 인수인 경우) 부작용을 포함할 수 있을 때 유용해집니다.그런 다음 중간에 피연산자를 반복하면 부작용이 두 번 수행됩니다.중간 피연산자를 생략하면 이미 계산된 값이 다시 계산할 때의 바람직하지 않은 효과 없이 사용됩니다.
가독성 및 휴대성을 위해 이를 피하는 것이 좋습니다.저는 솔직히 C의 문법과 호환되지 않는 확장을 보고 놀랐습니다.
이것은 "조건이 참이면, 사용하라, 그렇지 않으면 이 다른 값을 사용하라"를 의미하는 GCC 확장자입니다.
machine->max_cpus = machine->max_cpus ?: 1;
의 줄임말입니다.
machine->max_cpus = machine->max_cpus ? machine->max_cpus : 1;
조건부에 부작용이 있는 경우에도 한 번만 실행됩니다.
gcc의 -pedicantic 플래그를 사용하면 다음과 같이 표시됩니다.
foo.c:5: 경고: ISO C는 ?: 식을 생략하는 것을 금지합니다.
이것은 GCC 확장판이며, 그 상태가 부작용을 가지고 있을 때 더 흥미롭고 유용하게 됩니다.
이 경우, 네, 저는 그것이 다른 무엇보다도 모호하다는 것에 동의합니다.
K&R BNF는 "?"와 ":" 사이에 식을 입력해야 함을 나타냅니다.저는 gcc가 진단 없이 그것을 편집해서는 안 된다고 생각합니다.
이것에 대한 또 다른 유용한 사례가 있습니다. 0을 반환할 수 있는 함수나 메서드를 호출할 때 중간 변수를 제거합니다. 두 번 호출하는 것을 피하고자 합니다.예를 들어 (Objective-C), 파일이 있는 경우 어레이로 압축을 풀고, 그렇지 않은 경우 빈 어레이를 반환하려고 합니다.
- (NSArray*)hydrateBacklogFromFile:(NSString *path)
{
NSArray *backlog = @[];
NSData *backlogData = [NSData dataWithContentsOfFile:path];
if (backlogData)
{
backlog = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData] ?: backlog;
}
return backlog;
}
대안은 덜 간결합니다.
- (NSArray*)hydrateBacklogFromFile:(NSString *path)
{
NSArray *backlog = @[];
NSData *backlogData = [NSData dataWithContentsOfFile:path];
if (backlogData)
{
NSArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData];
if (tempArray != nil)
{
backlog = tempArray;
}
}
return backlog;
}
또는 복수의 반품 등이 있는 더 추한.
- (NSArray*)hydrateBacklogFromFile:(NSString *path)
{
NSData *backlogData = [NSData dataWithContentsOfFile:path];
if (backlogData)
{
NSArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData];
if (tempArray != nil)
{
return tempArray;
}
}
return @[];
}
그래서 제가 꽤 읽을 수 있는 유용한 통사 설탕입니다.단점은.
포인터를 암시적으로 부울로 변환합니다.이것은 오래된 C 규약이지만, 대부분의 현대 언어들은 그것을 허용하지 않고, 어떤 이식 작업도 복잡하게 만듭니다.
다른 사람들이 말했듯이, 그것은 또한 비표준 확장이기 때문에 휴대성을 고려한다면 피해야 합니다.
다른 답변이 제목의 질문에 답하지 않고 태그도 가져가지 않는 것 같습니다.c
을 덧붙입니다.따라서 저는 다른 답변을 추가합니다.
이 구문을 사용하여 if-문을 통해 코드가 추해지는 것을 방지합니다.
foo(1) == TRUE ?: error_quit("foo(1) failed");
foo(2) == TRUE ?: error_quit("foo(2) failed");
foo(3) == TRUE ?: error_quit("foo(3) failed");
foo(4) == TRUE ?: error_quit("foo(4) failed");
줄의 시작 부분에서 실제 함수 호출을 볼 수 있습니다.아래 버전과 비교하여 선두 제품이if
함수 호출의 직접 보기를 방해합니다.
if (foo(1) == FALSE) error_quit("foo(1)" failed");
if (foo(2) == FALSE) error_quit("foo(2)" failed");
if (foo(3) == FALSE) error_quit("foo(3)" failed");
if (foo(4) == FALSE) error_quit("foo(4)" failed");
또는 읽기가 더 어렵습니다.
if (foo(1) == FALSE){
error_quit("foo(1)" failed");
}
if (foo(2) == FALSE){
error_quit("foo(2)" failed");
}
if (foo(3) == FALSE){
error_quit("foo(3)" failed");
}
if (foo(4) == FALSE){
error_quit("foo(4)" failed");
}
언급URL : https://stackoverflow.com/questions/2806255/why-would-you-use-the-ternary-operator-without-assigning-a-value-for-the-true
'programing' 카테고리의 다른 글
파이썬을 사용하여 웹 페이지에 로그인하고 나중에 사용할 쿠키를 검색하는 방법은 무엇입니까? (0) | 2023.07.17 |
---|---|
Django 템플릿 내 인덱스별 참조 목록 항목? (0) | 2023.07.17 |
공백 없이 텍스트를 단어 목록으로 분할하는 방법 (0) | 2023.07.17 |
파이썬에서 __init__의 값을 반환하는 방법은 무엇입니까? (0) | 2023.07.17 |
Chrome에서 Selenium WebDriver Python 바인딩 실행 (0) | 2023.07.17 |