2017-04-17 18 views
-1
struct st 
{ 
    int a1 : 3; 
    int a2 : 2; 
    int a3 : 1; 
} 

void main(void) 
{ 
    x.a3 = -1; 

    if (x.a3 == -1) printf("TRUE\n"); 
    else printf("FALSE\n"); 

    x.a3 = 1; 
    if (x.a3 == 1) printf("TRUE\n"); 
    else printf("FALSE\n"); 
} 

경우에 따라 'x.a3 = -1;' 첫 번째 경우는 TRUE입니다.
그러나 'x.a3 = 1'이 두 번째로 변경되지 않는 이유는 무엇입니까? 여전히 x.a3 = -1입니다.구조 변수가 지정에 의해 변경되지 않음


'x.a3 = 1;'을 입력하면 처음에는 x.a3 = = 1! 그것은 변하지 않습니다!

Debug Result in XCode

+0

'void main()'은 유효하지 않은 서명입니다. 최소한의 서명은'int main (void)'이다. 'x' 란 무엇입니까? 코드가 컴파일되지 않습니다. [mcve]를 제공하십시오. – Olaf

+0

@Olaf C11 5.1.2.2.1 2를 읽으면서 "반환 유형 int 또는 다른 구현 정의 방식으로 정의해야합니다." 'void main (void)'는 유효하다면 틀림없이 유효하다면 구현 정의된다. 나는 그것이 "또는"에 달려 있다고 생각합니다. IAC, 확실히 OP의 핵심 문제는 아닙니다. – chux

+0

@chux : 이것은 해석의 대상입니다. 따로 말하자면, 모든 풀 사이즈 OS는'int' 결과를 요구합니다. – Olaf

답변

3

문제는, 서명 1 비트 변수는 두 개의 값, -10를 (약 Two's complement 읽기) 보유 할 수 있습니다. 1 (+ 1) 값을 보유하는 것으로는 충분하지 않습니다. 가변의 부호의 당 멤버 a3 예약 된 메모리 위치에 저장되어있는 할당

x.a3 = 1; 

1 일정한 정수 값을 기록하는 동안, 그러나 변수에 액세스하는 동안

는 (부연 어쩌면 signed 또는 unsigned, 구현 정의 된 동작, §6.7.2/P5)에 따라 표현이 메모리에서 읽혀집니다.

2의 보수에서의 1 저장된 값의 표현은, 반드시 그렇게 == 1와 조건 체크가 실패 (MSB의 값에 따라) -1 결과를 생성한다.

+1

비트 필드의 일반 int가 부호가 있거나 부호없는 값인지 여부가 정의되어 있습니다. 비트 필드에 관한 거의 모든 것은 구현 정의되어 있습니다. –

+0

@chux 저를 바로 잡아 주셔서 감사합니다. 어떻게 든 이전 의견을 놓쳤습니다. 업데이트되었습니다. –

0

필드 a3은 1 비트 int이므로 0 인 경우 (비트가 0 인 경우) 또는 -1 (부호 비트 인 비트가 1 인 경우) -1 만 유지할 수 있습니다. . 따라서 값 1을 할당하려고하면 해당 값의 표현이 저장되고 주어진 데이터 유형의 표현은 -1이됩니다.

1 비트의 int에있는 값 -1이 1 비트의 unsigned int에서 값 1과 동일한 표현을 가지므로 같은 것을 비교하지 않는다고해서.

0
int a3 : 1; 

은 var를 저장하는 데 사용할 공간을 정의하는 비트 필드가있는 구조체입니다. a1에 -1과 0 값만 저장할 수있는 1 비트의 부호있는 int를 작성합니다. a3에 값 1을 넣으려는 경우 의도 한 구문은 int a3 = 1이고 여러 가지 방법 중 하나입니다. 그렇게 할 수 있습니다.

struct st 
{ 
    int a1 : 3; 
    int a2 : 2; 
    int a3 : 1; 
}; 


void main(void) 
{ 
    struct st x = {1,2,3}; 
    x.a3 = -1; 

    if (x.a3 == -1) printf("TRUE\n"); 
    else printf("FALSE\n"); 

    x.a3 = 1; 
    if (x.a3 == 1) printf("TRUE\n"); 
    else printf("FALSE\n"); 
}