2010-11-22 3 views
6

다음 코드를 컴파일하면 컴파일러에서 다음 줄이 항상 true라는 오류가 발생합니다. 나는이 조건이 항상 true입니까? (pktNum! = invPktNum)

if (pktNum != ~invPktNum) { 
    return 1; 
} 

내가 그 invPktNum을 확인하기 위해 노력하고있어 실제로 pktNum의 역입니다 ... 나는 != 운영자의 잘못된 이해를 가질 수있다 생각합니다. 그렇지 않은 경우 즉시 종료하고 그렇지 않으면 정상적으로 진행하십시오.

pktNum은 0x01이고 unsigned char는 0x35이고 invPktNum은 비교시 0xFE 인 부호없는 char입니다.

누구나 나를 밝힐 수 있습니까? 미리 감사드립니다!

답변

10

C에서 int보다 좁은 형식 인 대부분의 식의 값은 계산이 수행되기 전에 더 넓은 형식으로 승격됩니다. int이 너비 유형의 모든 값을 보유 할만큼 충분히 넓 으면 int으로 승격됩니다. 그렇지 않으면 unsigned int으로 승격됩니다.

이 경우 intunsigned char의 모든 값을 보유 할만큼 충분히 넓기 때문에 값은 int으로 올라갑니다.

pktNum (따라서 프로모션 된 pktNum)은 0과 255 사이의 값을 가질 수 있습니다. 이 값은 != 연산자의 왼쪽에 사용될 값입니다.

invPktNum도 마찬가지로 0과 255 사이의 값을 가질 수 있습니다. 이 값은 int으로 승격되고 비트 단위 부정됩니다. 부호 비트가 부정되기 때문에이 비트 부정 결과는 항상 음수입니다. 이 값은 != 연산자의 오른쪽에 사용될 값입니다.

음수는 승격 pktNum과 같을 수 없으므로 조건은 항상 true입니다.

는 당신이 실제로, 당신은 부정 후 하위 8 개 비트를 마스크해야 할 계산을 수행하려면 :

if (pktNum != (~invPktNum & 0xff)) { 
    return 1; 
} 

또는 대안을, 당신은 당신이 관심있는 비트를 부정 할 수

if (pktNum != (invPktNum^0xff)) { 
    return 1; 
} 
+0

아, 이것이 그랬고 - 나는 새로운 것을 배웠습니다. 당신의 멋지고 상세한 답변에 감사드립니다! – Justin

+0

@ FallSe7en : 놀랍도록 혼란스러운 C 코드 디버깅 세계에 오신 것을 환영합니다. 컴파일러 경고없이 버그를 찾으려고한다고 상상해보십시오! –

0

8 비트 값을보고 있습니다. pktNum과 invPktNum은 32 비트 값이므로 0x000000fe와 0xfffffffe를 비교할 수 있습니다.

+0

16 비트 마이크로 컨트롤러 용 코드를 작성하는 경우 부호없는 char은 16 비트가됩니까? 나는 unsigned char가 단지 8 비트라고 생각했다. – Justin

+0

'char'는'CHAR_BIT'에서''(내가 생각하는 것)을 정의합니다. – dennycrane

+0

어떤 유형입니까? 당신은 당신의 질문에 그것을 지정하지 않았습니다. – EboMike

-1

다음과 같은 가정 :

invPktNum = ~pktNum 

을 다음 비교하는 것과 같습니다

if (pktNum != ~(~pktNum)) { 

또는

항상 false입니다
if (pktNum != pktNum) { 

. invPktNum에 코드에 다른 정의가 표시되지 않는 한 표시되지 않습니다.

+1

컴파일러는 항상 * true *라고 불평합니다. – caf

+0

invPktNum 및 pktNum의 완전한 선언을 원래 질문에 추가 할 수 있습니까? – uesp

0

아마도 단순형 독립 테스트는 다음

if (0 == (pktNum & pkNum)) { 

어느 I

빠르게 http://codepad.org/nziOGYJG 테스트
if (0 == (0xfe & 0x01)) { 

서명 여러 및 부호없는 긴/INT 유형으로 작동하는 것 같다 : 같에요.

관심있는 사람이 있으면 누구든지 댓글이 있습니까?

+1

그건 의도 된 원본과 같은 의미를주지 않는다. 이것은 입력 중 하나가 0 일 때만 참일 수있다.'if ((pktNum^invPktNum)! = 0xff)'는 작동하지만, 그것이 분명하다고 생각하지 마십시오. – caf

+0

@caf 감사합니다. 나는 그것이 명확하지 않은 것에 동의한다. –

관련 문제