Q & A

구조체(공용체)의 최대 멤버 개수는 몇 개인가요?

C 언어 표준에는 1,023개로 정의되어 있으며 컴파일러마다 최대 개수는 달라질 수 있습니다.

두 구조체의 내용이 같은지 어떻게 알 수 있나요?

다음과 같이 구조체가 있고 변수를 선언했을 때 비교 연산자로는 두 구조체의 내용이 같은지 알 수 없습니다(컴파일 에러 발생).

struct Person {
    char name[20];
    int age;
    char address[100];
};

int main()
{
    struct Person p1;    // 구조체 변수
    struct Person p2;    // 구조체 변수

    // 생략 ...

    if (p1 == p2) { ... }    // 컴파일 에러

이때는 어쩔 수 없이 구조체 변수의 모든 멤버를 비교해야 합니다. 두 구조체의 멤버에 저장된 값이 모두 같다면 두 구조체의 내용은 같습니다.

struct Person p1;
struct Person p2;

// 생략 ...

// 구조체 변수의 모든 멤버를 비교
if (strcmp(p1.name, p2.name) == 0 &&               // 문자열은 strcmp 함수로 비교
    p1.age == p2.age &&                            // 숫자는 ==로 비교
    strcmp(p1.address, p2.address) == 0) { ... }   // 문자열은 strcmp 함수로 비교

구조체를 포인터로 선언하고 메모리를 할당했을 때는 포인터 자체를 ==로 비교하면 됩니다. 즉, 포인터를 비교하면 메모리 주소가 같은지 비교하게 되므로 두 포인터에 저장된 메모리 주소가 같다면 두 구조체의 내용은 같습니다. 같은 메모리 공간을 가리키는데 안에 저장된 값이 서로 다를 수는 없기 때문이죠. 만약 한쪽 포인터를 통해 멤버의 값을 바꾸면 메모리의 내용이 바뀌므로 다른쪽 포인터에서 봤을 때도 바뀐 값이 보이게 됩니다.

struct Person *p1;    // 구조체 포인터
struct Person *p2;    // 구조체 포인터

// 생략 ...

// 구조체 포인터는 포인터 자체를 비교
if (p1 == p2) { ... }    // 포인터는 ==로 비교할 수 있음

따라서 구조체 포인터는 일일이 멤버의 값을 비교하지 않아도 됩니다.

struct와 typedef struct의 차이점은 무엇인가요?

첫 번째 A는 구조체 태그(structure tag)이며 두 번째 Btypedef로 정의한 자료형 이름(타입 이름)입니다. 그래서 첫 번째의 타입 이름은 struct A이며 두 번째의 타입 이름은 B입니다.

struct A { ... };
typedef struct { ... } B;

그래서 구조체 태그로는 변수나 포인터를 선언할 수 없기 때문에 struct A와 같이 struct를 붙여서 타입 이름으로 만들어주는 것입니다.

구조체 태그와 typedef 타입 이름 두 가지 방식을 모두 적용할 수도 있습니다.

typedef struct C { ... } C;

구조체 태그 이름과 타입 이름이 겹치긴 하지만 태그 이름과 타입 이름은 서로 다른 이름공간(namespace)에 속하기 때문에 허용되는 문법입니다(처음에는 태그 이름만 있었지만 나중에 typedef가 추가되어 이런 모양이 된 것입니다).

참고로 C 언어는 네 개의 이름공간이 있습니다.

  • goto에서 쓰이는 레이블
  • 구조체, 공용체, 열거형의 태그
  • 구조체, 공용체의 멤버
  • 함수, 변수, typedef타입 이름, 열거형의 값

구조체를 정의할 때 struct와 typedef를 분리할 수는 없나요?

struct로 구조체를 정의한 뒤에도 따로 typedef를 사용하여 구조체 별칭을 정의 할 수 있습니다.

struct Person {    // struct로 구조체 정의
    char name[20];
    int age;
    char address[100];
};

typedef struct Person PERSON;    // typedef를 사용하여 struct Person을 PERSON으로 정의
typedef struct Person Person;    // 구조체 이름(태그)와 별칭(타입 이름)을 동일하게 정의

struct Person p1;    // struct Person으로 변수 선언
PERSON p2;           // PERSON으로 변수 선언
Person p3;           // Person으로 변수 선언