2016-09-13 10 views
26

내 조직의 소스 저장소를 정독하는 동안 나는이 작은 보석을 가로 질러왔다? (그것이 컴파일됩니다) 여기서 느낌표는 무엇을합니까?배열 색인의 느낌표는 무엇을합니까?</p> <pre><code>RawParameterStorage[!ParameterWorkingIdx][ParameterDataOffset] = ... </code></pre> <p>이 유효 코드 :

반올색 ~ 연산자는 부울 식의 ! 연산자와 일반적으로 혼동되기 때문에 의미가 있습니다. 그러나 배열 인덱스에 ! 연산자를 부과하는 것은 논리적 인 의미가없는 것처럼 보입니다. 이견있는 사람?

답변

42

!ParameterWorkingIdx는 경우 !ParameterWorkingIdx 암시 (어레이에서와 같이 정수 인덱서에 대해 예를 들어, 1) 인덱서 형태로 변환 할 수 true로 평가, 그렇지 않으면 false으로 평가하여 0이다.

  • ParameterWorkingIdx == 0 다음 [!ParameterWorkingIdx] == [1]합니다.

  • ParameterWorkingIdx != 0이면 [!ParameterWorkingIdx] == [0]입니다.

또한 같은 다른 재료에 따라 달라집니다

  • ParameterWorkingIdx의 유형입니다.

  • ! operator의 오버로드는 ParameterWorkingIdx입니다.

  • 인덱서 오버로드 유형은 RawParameterStorage입니다. 이 유효한 코드 등

  • ...

+12

''You "+ ["are ","are not "] [! loggedIn()] +"logged in "'← 자바 스크립트에서 같은 생각의 예. 동의하지 않았지만 C의 잘못은 아닙니다! – j6m8

+0

첫 문장에서 "다른 것"을 제거해야한다고 생각합니다. 현재의 형태에서는 당신이 말하고자하는 것과 반대입니다. – CodesInChaos

+1

@ j6m8 JS에서와 같이 실제로 작동하지 않는 속성은 문자열로 캐스트되고 부울은 결국 "true"/ /' "false"'로 끝납니다. 그러므로 ""You "+ ["not ","are "] [+ loggedin()] +"logged in "또는" "You"+ {false : "are not", true : "are" [loggedIn()] + "logged in"\ – Bergi

8
는 배열 인덱스 그것은 수도

에하지 ! 연산자를 부과하는 논리적 이해하지 않는 것

: 그것은 여기 않습니다 모두 하나에 제로 전환하고, 제로에 다른 수 .

이 코드에서 RawParameterStorage에는 최상위 레벨에 두 개의 요소가있을 것이라고 추측 할 수 있습니다.

P.S 여기에서 나는 RawParameterStorage이 배열이라고 가정합니다. 또한 ParameterWorkingIdx은 (이름에서 알 수 있듯이) 정수라고 가정합니다. 예를 들어, 둘 중 하나가 과부하 된 연산자를 사용하는 클래스 인 경우 의미가 완전히 다를 수 있습니다. 수단 ParameterWorkingIdx

+2

UV가되었지만, 이것은'ParameterWorkingIdx'가 오버로드 된 클래스의 인스턴스가 아니라고 가정합니다! 운영자. OP가 그것을 확인하는 것이 현명 할 것입니다. – Bathsheba

+0

@Bathsheba : 공정한 지적. 완성을 위해 몇 마디를 추가하겠습니다. – NPE

3

인가?

예입니다.operators ! 사용할 때 !ParameterWorkingIdx 들어, intParameterWorkingIdx을 가정, 그것은

contextually convertible to bool있을 것이다 제로 널 포인터와 널 포인터 (정수, 부동 소수점, 및 범위가 지정되지 않은 열거) 멤버 값은 false이됩니다. 다른 모든 값은 true이됩니다.

그런 다음 integral promoted을 배열 색인으로 사용하십시오.

유형의 부울

은 1

그래서 !ParameterWorkingIdx IMO 훨씬 더 분명하다 ParameterWorkingIdx == 0 ? 1 : 0와 동일합니다되고 0 true되고 값 false으로 int로 변환 할 수 있습니다.

+0

직접 작성한 목적이 분명하지는 않지만 코드 작성시 분기 코드를 생성하지 않아도된다. – XapaJIaMnu

+0

@XapaJIaMnu 우리는 인간을위한 코드를 작성하고있다. 컴퓨터뿐만 아니라 읽을 수 있습니다. :) – songyuanyao

+2

이 청크의 성능이 중요한 경우 분기 명령을 피하는 것이 도움이됩니다. 3 가지 조건부 버전을 주석으로 추가하십시오. 또는 평범한 영어 버전. –

19

여기에 약간의 추측을하고 있지만 이중 버퍼 패턴처럼 보입니다. ParameterWorkingIdx01 (아마도 ParameterWorkingIdx = !ParameterWorkingIdx;) 사이에서 플립 플롭합니다.

그러면 언제든지 RawParameterStorage[ParameterWorkingIdx]이 현재 버퍼가되고 RawParameterStorage[!ParameterWorkingIdx]은 이전 버퍼가됩니다.