2013-11-04 2 views
0

내가이 구조를 초기화 할 :C에서 공용체에서 포인터를 사용하는 방법은 무엇입니까?

typedef struct 
{ 
    int num; 
    union 
    { 
     const char** ppStrList; 
     const char* pStr; 
    }; 
    union 
    { 
     int num1; 
     int num2; 
    }; 
} tMyStruct; 

나는 내가 오류가 발생하는 변수를 선언 할 때이 구조를 초기화하려고하면 예를 들어;

const char *gpStr = "str"; 

const char *gpStrList[2] = 
{ 
    {"str1"}, 
    {"str2"} 
}; 

tMyStruct myStruct[2] = 
{ 
    {0,{gpStrList},{3}}, 
    {1,{gpStr},{4}} 
}; 

변수 gpStr 구조

을 초기화 할 수 할수 없어 그러나이 문제없이 함수의 내부 초기화 할 수 있습니다 :

int main(int argc, char *argv[]) 
{ 
    myStruct[0].num = 0; 
    myStruct[0].ppStrList = gpStrList; 
    myStruct[0].num1 = 3; 

    myStruct[1].num = 0; 
    myStruct[1].pStr = gpStr; 
    myStruct[1].num2 = 3; 
} 

구조를 초기화 할 수없는 이유 그것이 선언되었을 때?

내가 노동 조합을 사용하지 않으면 문제가 존재하지 않기 때문에 노동 조합에 특수한 행동이 있다고 생각합니다. 예를 들면 :

typedef struct 
{ 
    int num; 
    union /* Union to contain ppStrList and pStr pointers */ 
    { 
     const char** ppStrList; 
     const char* pStr; 
    }; 
    union 
    { 
     int num1; 
     int num2; 
    }; 
} tMyStruct1; 


typedef struct 
{ 
    int num; 
    /* I don´t use an union */ 
    const char** ppStrList; 
    const char* pStr; 

    union 
    { 
     int num1; 
     int num2; 
    }; 
} tMyStruct2; 

const char gStr[] = "str"; 

const char *gpStrList[2] = 
{ 
    {"str1"}, 
    {"str2"} 
}; 

tMyStruct1 myStruct1[2] = /* Structure with union inside */ 
{ 

    {0,{gpStrList},{3}}, 
    {1,{gStr},{4}} /* <--- Error here if I use gStr address with union */ 
}; 

tMyStruct2 myStruct2[2] = /* Structure without union inside */ 
{ 
    {0,gpStrList,NULL,{3}}, 
    {1,NULL,gStr,{4}} /* <--- No poblem here if I use gStr address */ 
}; 
+0

나는이 아마 ... 일 것 int num2; }, ' 은 노동 조합을 전혀 사용하지 않아야 함을 증명합니다. – Dariusz

답변

3

파일 범위 (static과 관계 없음)에서 초기화 된 변수와 static 지속 기간으로 블록 범위에서 초기화 된 변수는 상수로만 초기화 할 수 있습니다. 자동 변수 (반드시 블록 범위에 있음)는 표현식으로 초기화 할 수 있습니다.

또한 공용체가 초기화 될 때 지정된 이니셜 라이저가 사용되는 경우를 제외하고는 이니셜 라이저가 첫 번째 멤버와 일치해야합니다. C99 이상으로, 당신은 쓸 수 :

typedef struct 
{ 
    int num; 
    union 
    { 
     const char** ppStrList; 
     const char* pStr; 
    }; 
    union 
    { 
     int num1; 
     int num2; 
    }; 
} tMyStruct; 

const char gpStr[] = "str"; 

const char *gpStrList[2] = 
{ 
    "str1", 
    "str2" 
}; 

tMyStruct myStruct[2] = 
{ 
    { .num = 0, { .ppStrList = gpStrList }, { .num1 = 3 } }, 
    { .num = 1, { .pStr  = gpStr  }, { .num2 = 4 } }, 
}; 

gpStr의 불통 유형입니다. 모든 요소에 대해 지정된 이니셜 라이저를 사용할 필요는 없지만 일관성을 유지하면 좋습니다. 또한 두 개의 다른 이름의 int 구성원의 조합은 알맞은 의미가 없습니다. 노동 조합의 다른 요소는 일반적으로 다른 유형이어야합니다.

+0

나의 겸손한 기부금보다 훨씬 명확하고 완벽합니다! 내 표를 얻는다! – Floris

+0

'union '을 초기화하려면 지정된 초기화 프로그램을 사용해야합니다. 서로 다른 이름의 'int'멤버들의'union '에 대해서. 동의합니다. 명확히하기 위해 코드는 실제 문제를 나타내지 만이 코드는 교훈적인 목적으로 만 만들어졌습니다. – leiva

+0

@leiva : 충분히 공평하고 그리 놀라운 일은 아닙니다. 단지 사소한 토론의 장소였습니다. 두 개의 다양한 유형 (아마도 int와 char *)을 여분의 유니온에서 사용하거나 두 번째 유니온을 예제에서 벗어나서 다시 확인해야하는 경우 이러한 주석을 무시할 수 있습니다. –

0

비 과학적 답 :

당신은 상수를 초기화 할 수 있다고 생각합니다. 첫 번째 인스턴스에서는 변수를 사용하여 초기화 (즉, 프로그램을 실행하기 전에 값 할당)합니다. 정의에 따르면 변수는 프로그램이 실행될 때까지 "액세스 가능"값을 갖지 않습니다. 두 번째 예제에서 "초기화"는 실제로 변수에 대한 "할당"이며, 이는 정상입니다. 나는 그것이 당신이 노동 조합에 있다는 사실과 아무런 관련이 없다고 생각합니다.

간단한 예 :

#include <stdio.h> 
int one = 1; 
int two = one; 
int main(void) { 
    printf("one is %d; two is %d\n", one, two); 
} 

내가 컴파일하려고

, 나는
consts.c:3: error: initializer element is not constant 

나는이 일을 명확히 희망

를 얻을.

+1

"C"라고 쓰여진 바로 다음 질문에 "warning : initializer 요소가 일정하지 않습니다"라는 제목이 있습니다. 분명히 전염병이 있습니다! – Floris

0

명시 적 지정자를 사용하지 않는 한 문제는 유니언의 첫 번째 요소 만 초기화 할 수 있다는 것입니다. 그래서 다음 작품 : `노동 조합 { INT의 NUM1;

tMyStruct myStruct[2] = 
{ 
    {0,{gpStrList},{3}}, 
    {1,{.pStr = "str"},{4}} 
}; 
관련 문제