유니온(Unions)은 사용할 때마다 다른 형과 다른 크기를 가실주 있는 변수인데 컴파일러가 크기와 정렬제한이 맞는지를 조사한 후 사용된다. 유니온은 프로그램이 기계에 종속되지 않으면서도 한 기억장소 내에 서로다른 데이터를 처리할수 있도록 한다.

예를 들어 컴파일러의 심벌 테이블에서 상수가 intfloat나 문자의 포인터라고 하자. 각 상수의 값은 그에 맞는 형의 변수에 기억되어야 한다. 그러나 만약 그 값이 똑같은 양의 기억 장소를 차지하고 그 형에 관계 없이 같은 장소에 기억될 수있다면 테이블 관리에 편리할 것이다. 이와 같이 변수가 어떤 임의의 형도 가질수 있도록 하는것이 바로 유니온의 목적이며 그 문법은 구조체에 근거를 두고있다.


union u_tag {

    int ival;

    float fval;

    char *sval;

} u;


변수 u는 컴파일되는 기계에 관계없이 세 가지 형 가운데 가장 큰 것을 가질수 있을 칸큼 충분히 크기 때문에 이 프로그램은 하드위어의 특성과 무관하게 된다. 이 세가지 형 가운데 어느것 이라도 u에 할당되어 수식에서 사용될수 있지만 유니온에 기억할 때의 형과 사용되는 수식 내에서의 형은 같아야 한다. 현재 유니온에 어떤형이 기억되며 있는지를 알아내는 것은 프로그래머가 해야 한다. 그형이 맞지 않을 경우에는 기계에 따라 그 결과가 달라진다. 문법상으로는 유니온의 멥버는 다음과 같이 표현된다.


유니온 이름.멤버


혹은 구조체와 같이 다음과 같이 쓸수 있다.


유니온의 포인터 ->멤버


만약 변수 utype이 현재 기억된 u의 형을 기억하고 있다면 다음과 같은 프로그램도 가능하다.


if (utype == INT)

    printf("%d\n", u.ival);

if (utype == FLOAT)

    printf("%f\n", u.fval);

if (utype == STRING)

    printf("%s\n", u.sval);

else

    printf("bad type %d in utype\n", utype);


유니온은 구조체나 배열 안에 나타날수가 있고 또한 그 반대로도 된다. 구조체 내의 유니온의 멤버(그반대도 또한)를 엑세스 하는 표시법은 중첩된 구조체의 표시법과 똑같다. 예를 들어,구조체의 배열이 다음과 같이 정의될 때


struct {

    char *name;

    int flags;

    int utype;

    union {

        int ival;

        float fval;

        char *sval;

    } u;

} symtab[NSYM];


멤버 ival은 다음과 같이 사용될수 있다.


symtab[i].u.ival


그리고 문자열 sval은 다음과 같이 사용될 수있다.


*symtab[i].u.sval

symtab[i].u.sval[0]


결국 유니온은 모든 멤버의 기억장소 시작 위치가 같고 가장 큰 멤버도 표현할 수있는 크기를 가지며 유니온 내의 모든형에 적절하게 정렬되는 구조체 이다.구조체와 마찬가지의 똑같은 연산이 유니온에서도 허용된다.즉 정렬이나 전체를 하나로 복사하거나 번지를 얻거나 멤버를 액세스 하는것이 구조체와 같다. 유니온은 멤버중에 가장 처음에 나오는 멤버의 형으로 초기화 되므로 위에서 사용한 유니온은 정수 값으로 초기화 된다 제8장에서 기억장고 할당자(storage allocator)가 어떻게 변수를 기억장소에 정렬해 넣는지를 보여줄 것이다