본문 바로가기
C언어

[C언어] 구조체(structure) | 구조체 정의, 선언, 배열, 포인터

by 보보(BOBO) 2023. 2. 27.
💻 오늘의 목표 : 구조체 완전 정복

 

1. 구조체

- 하나 이상의 변수를 묶어서 사용하기 위한 자료형

- 의미상 연관 관계가 있는 항목을 그룹으로 묶어 표현한 자료형

=> 구조화된 데이터를 처리할 때 유용

(예시) 사람의 인적사항을 정리할 때, 이름, 전화번호, 사는 곳을 한 번에 묶어서 구조체에 저장할 수 있다.

 

우리가 많이 사용하는 int, char 자료형이 있듯이 구조체도 내가 원할 때 선언해서 사용하는 자료형이다.

 

  • 멤버(member) : 구조체를 구성하는 변수들

2. 구조체 정의, 선언, 사용

int, char 같은 자료형은 변수를 사용하기 전에 미리 선언이 필요했다.

int main() {
    int i; // 변수 선언
    scanf("%d", &i);

    printf("%d", i + 100);
}

하지만 구조체는 선언하여 사용하기 전에 내가 구조체 안에 어떤 변수를 저장해야 할지 정의해 주는 작업이 필요하다.

 

[구조체 정의]

=> 기본 형태

struct person { // 구조체_자료형_이름

    // 멤버_자료형 멤버_변수;
    char name[10];
    int phone_number;
    char address[20];

};

struct로 정의하고 그 뒤에는 내가 앞으로 사용할 구조체 자료형 이름을 넣어준다.

그리고 중괄호를 열고 안에는 내가 쓰고 싶은 멤버의 자료형과 변수 이름을 지정해서 적어준다.

그리고 중괄호 닫고 마지막에 세미콜론!

  • 기본 자료형, 배열, 포인터, 구조체까지 모두 멤버 자료형으로 사용이 가능하다.
  • 정의만 해줬을 뿐 아직 메모리 공간할당이 되지 않은 상태
  • 모든 함수에서 사용하기 위해 주로 함수 밖에 구조체를 정의함
  • 함수 안에서 정의한 구조체는 그 함수 안에서만 사용 가능

=> 다양한 정의 형태

1. 자료형 정의와 변수 선언 동시에 하는 경우

struct person { // 구조체_자료형_이름

    // 멤버_자료형 멤버_변수;
    char name[10];
    int phone_number;
    char address[20];

} person;

닫힌 중괄호 뒤에 변수를 선언해 준다.

선언하는 동시에 변수 초기화도 가능하다.

//맨 마지막 줄
} P = {"Justin", 123456, "NewYork" };

2. 구조체 자료형 이름 생략하는 경우

(자료형 이름이 없으므로 다른 곳 사용 불가능)

struct {

    // 멤버_자료형 멤버_변수;
    char name[10];
    int phone_number;
    char address[20];

}person;

이때는 구조체 마지막에 선언한 전역변수 person만 선언이 가능하다.

 

[구조체 선언, 초기화]

이제 정의한 구조체를 선언하여 데이터를 저장할 수 있는 메모리를 할당시켜주어야 한다.

//구조체 선언
struct person P1, P2;

위와 같은 방식으로 'struct 구조체_자료형_이름 변수이름; ' 으로 선언할 수 있다.

 

(메모리 공간)

  • 구조체 자체는 메모리 공간을 따로 할당받지 않는다.
  • 구조체 안에 멤버 변수들의 공간이 각 자료형의 크기대로 각각 할당된다.
char name[10] int phone_number char address[20]

(주의) 구조체 전체의 메모리는 각 멤버들의 메모리 합이 아닐 수 있다.

=> 구조체의 메모리 할당 공간을 알고 싶을 땐 sizeof 연산자 사용할 것

 

(초기화)

이제 초기화를 해보자

맨 처음 선언하면서 값을 중괄호 안에 나열하여 초기화시켜 줄 수 있다.

//구조체 선언
struct person P1 = {"Justin", 123456, "NewYork" };
char name[10] int phone_number char address[20]
Justin 123456 NewYork

 

[구조체 멤버 변수 사용]

구조체 변수는 구조체 멤버 전체를 나타내고, 만약 멤버 하나에 접근하고 싶다면 구조체 멤버 연산자(.)를 사용한다.

//구조체 변수.멤버변수
P1.phone_number;

 

[구조체 사용가능 연산자]

  • 산술 연산, 비교 연산 지원되지 않음
  • 제한적인 연산자 : 대입 연산자, 주소 연산자, 간접 참조 연산자, sizeof

3. 구조체 배열

구조체 변수들도 묶어서 배열로 쓸 수 있다.

 

[구조체 배열 선언]

 

struct person { // 구조체_자료형_이름

    // 멤버_자료형 멤버_변수;
    char name[10];
    int phone_number;
    char address[20];

};

int main(void) {
	// 구조체 배열 선언
    struct person P[5];

    P[0].phone_number = 123;

}​

이런 방식으로 구조체 배열을 사용할 수 있다.

선언과 동시에 초기화해 줄 수도 있다.

int main(void) {
    //선언 동시에 초기화 (생략된 부분은 0으로 초기화됨)
    struct person P[5] = { {"ABC", 123, "1-1"}, {"DEF", 456, "2-2"} };

}

이때 주의할 점은 꼭 중괄호 안에 데이터들을 나열해 주어야 한다는 것.

 

4. 구조체 포인터

<연산자 우선순위 주의할 것>

더보기

<정의된 구조체>

struct person { // 구조체_자료형_이름

    // 멤버_자료형 멤버_변수;
    int id;
    int phone_number;
    char* pname;

};

1. 포인터가 구조체의 멤버로 사용되는 경우

int main(void) {
    
    struct person p1;

    //문자 포인터에 문자열 연결
    p1.pname = "ABC";

    printf("%s\n", p1.pname);   //문자열 출력
    printf("%c\n", p1.pname[0]); // 0번 인덱스 문자 출력
    printf("%c\n", *p1.pname);  //문자 출력(포인터 간접 참조)

}

2. 구조체를 가리키는 포인터 (구조체 포인터)

  • 구조체 포인터 변수를 선언하려면 참조 연산자 * 사용
int main(void) {
    
    struct person P1 = { 1 , 123456, "Justin" }, P2;
    struct person *pp;

    pp = &P1; // 구조체 포인터 연결
    P2 = *pp; //간접 참조 P1==P2

}

간접 참조를 이용하여 구조체 변수의 멤버에 접근하려면?

  • 포인터가 가리키는 구조체에 접근하기 위해 참조연산자 * 사용
  • 구조체 멤버에 접근하기 위해 멤버 연산자. 사용
  • 멤버 연산자 우선순위 > 참조 연산자 우선순위 (괄호 필요)
int main(void) {
    
    struct person P1 = { 1 , 123456, "Justin" }, P2;
    struct person *pp;

    pp = &P1; // 구조체 포인터 연결
    P2 = *pp; //간접 참조 P1==P2

    (*pp).id = 2; //멤버 변수 간접 참조

}

그러나 항상 사용할 때마다 괄호를 쓰는 것이 불편하기 때문에 구조체 포인터 전용 참조 연산자 (->) 가 있다.

pp->id = 2;

 

3. 구조체 포인터가 배열의 원소로 사용되는 경우(구조체 배열 포인터)

int main(void) {
    
    struct person P1 = { 1 , 123456, "Justin" }, P2;
    struct person* pp[4] = { &P1, &P2 }; // 구조체 포인터 배열 선언, 초기화

    pp[2] = pp[1];
    *pp[2] = *pp[0];

    pp[1]->id = 3;

}

 

구조체 배열 구조체 포인터 구조체 포인터 배열
struct person p[5]; struct person *p; struct person *p[5];

컴퓨터 프로그래밍 전공하는 대학생이 공부했던 내용을 정리하기 위해 적는 소소한 블로그입니다.
잘못된 내용은 댓글에 달아주시면 피드백 감사히 받겠습니다!

[참고한 도서]

- 실전 C프로그래밍

댓글