본문 바로가기

Language/C++

[C++] 구조체

728x90
반응형

배열 원소의 타입은 모두 동일해야 한다. 하나의 배열에서 어떤 원소는 char이고 어떤 원소는 int 일 수 없다. C++에서는 배열로 해결하지 못하는 문제를 구조체를 이용하여 해결할 수 있다. 원소의 크기가 제각각인 배열을 만드는 것이다. 배열에서는 배열의 타입만으로 모든 원소의 타입을 알 수 있었지만 구조체는 그렇지 않기 때문에 정의할 때 모든 원소의 타입을 명시해 주어야 한다.

struct 구조체이름 {
    멤버들..예를 들면 char str[10];
    int i;
}; /* 마지막에 꼭 ;를 붙인다. */

 

Human이라는 이름의 구조체는 3개의 멤버(int age, int height, int weight)를 가지고 있다. main 함수 내에서 Human이라는 구조체의 구조체 변수 Psi를 정의하였다. 여기서 놀라운 점은 struct Human이라는 것이 int형 변수를 정의할 때 int를 쓰는 것과 같이 사용되었다는 것이다. 이처럼 Psi를 정의하고 나면 Psi의 타입은 struct Human, 즉 Human 구조체가 된다.

 

배열에서 [ ] 를 이용해서 원소에 접근하듯이, 구조체에서도 멤버에 접근하는 방법이 있다. 예를 들어 Psi의 height 멤버에 접근하려면 Psi.height 라고 하면 된다.  ※ 구조체 정의 내부에서는 변수를 초기화 할 수 없다.  

 

구조체 포인터

int나 char과 같은 타입을 가리킬 때 포인터를 int*나 char*로 사용했던 것과 마찬가지로 struct test 역시 하나의 타입이므로 struct test*로 사용한다. struct test* ptr은 struct 형을 가리키는 포인터 ptr을 정의한 것이다. ptr은 절대로 구조체가 아니고 다른 포인터처럼 4바이트 공간을 차지하는 것이다.

 

ptr에 str의 주소값을 집어넣는다. 배열을 가리키는 포인터를 정의할 때 &를 붙이지 않지만, 구조체는 보통 변수처럼 (구조체 변수라 부르지, 구조체 '배열'이라고 부르지 않음) &를 붙여 구조체가 정의된 메모리 주소값을 얻어온다.

 

ptr이 st를 가리키고 있기 때문에 (*ptr)이라는 부분은 st와 동일하다. (*ptr).a = 1 은 st.a = 1 과 완전히 동일한 문장이다. 이 때 주의할 점은 괄호를 꼭 써주어야 한다. 구조체 멤버를 지칭할 때 사용하는 .은 *보다 우선순위가 높기 때문에 *ptr.a를 사용하게 되면 *(ptr.a)와 동일한 문장이 된다. ptr은 단순히 포인터이고 구조체가 아닌데 있지도 않는 a라는 멤버에 접근하라니 컴파일 시에 오류가 발생하는 것이다.

결과적으로 구조체 포인터를 사용해 멤버에 접근하려면 괄호로 감싸 주어야 하는데 귀찮으므로 새로운 기호 -> 가 등장했다.

add_one 함수에 t의 멤버 c의 주소값을 전달하였다. 역시 &보다 .이 우선순위가 높으므로 &t.c는 &(t.c)와 동일하다. add_one 함수에 의해 c의 값이 1 증가한다. 마찬가지로 &pt->c에서 &보다 ->가 우선순위가 높다. 따라서, pt가 가리키는 구조체의 멤버 c의 값이 1 증가하게 된다.

 

구조체의 대입

구조체도 보통의 변수들과 같이 =를 사용할 수 있다. st를 st2에 대입했다. st2의 멤버 i의 값은 st의 멤버 i의 값과 같아지고, st2의 멤버 c의 값은 st의 멤버 c의 값과 동일해졌다.

 

구조체를 인자로 전달하기

human 구조체 변수가 값이 초기화되지 않았다는 오류가 발생한다. 특정 변수의 값을 다른 함수를 통해 바꾸려면 변수의 주소값을 전달해야 한다는 룰을 지키지 않았기 때문이다. a.age = age; 를 했을 때 main함수에서의 human이 아니라 set_human함수의 a라는 human과 별개의 구조체 변수의 age 멤버의 값이 바뀌게 된다.

위 set_human 함수는 이전 예제와 다르게 구조체의 포인터를 인자로 취하고 있다. set_human 함수를 호출할 때에도 human의 주소값을 인자로 전달한다. 따라서 a는 human을 가리키게 된다.

 

주의할 점은 a->age와 age는 다르다는 것이다. a->age는 human 구조체 변수의 int형 멤버 age를 지칭하는 것이고, age는 단순히 set_human 함수에서 인자로 받아들여진 int 형의 age라는 변수를 가리키는 말이다.

 

구조체 안의 구조체

구조체는 사용자가 정의한 또 다른 형(type)이기 때문에 또다른 구조체 변수를 멤버로 가질 수 있다. '.'연산자의 우선 순위는 왼쪽부터이므로 Kim.data.age은 (Kim.data).age로 Kim의 data 멤버의 age 멤버를 의미한다.

 

구조체를 리턴하는 함수

 

구조체 변수의 정의 방법

구조체 변수를 정의하는 방법 중 위와 같이 색다른 방법이 있다. struct obj 형의 Ball이란 구조체 변수를 정의하라는 뜻이다.

위 예제는 이전까지 멤버를 초기화 해온 방법보다 쉽게 멤버를 초기화하는 방법이다.

728x90
반응형

'Language > C++' 카테고리의 다른 글

[C++] OOP - 생성자와 소멸자  (0) 2021.07.09
[C++] 공용체, 열거체  (0) 2021.07.03
[C++] 동적 할당  (0) 2021.07.01
[C++] 참조자(레퍼런스)  (0) 2021.06.30
[C++] 포인터  (0) 2021.06.28