1. 구조체형의 원리
이전 글에서 배운 사용자 정의형 enum과 같이, 구조체형(structure data type) 또한 프로그래머가 만들 수 있는 사용자 정의형 중의 하나이다. 구조체형은 다른 형들을 묶어주는 기능이 있는 것이 특징이다. 예를 들어, 차량 번호(int형)와 연료의 양(double형)과 같은 다른 형의 값을 하나로 묶어서 차의 기본적인 속성을 표현할 수 있는 것이다. (쉽게 이해하면, 차 라는 물체를 코드로 구현해 주는 것이다.)
구조체에 어떤 형을 묶을지 결정하는 일을 구조체형 선언이라고 한다. 구조체를 선언할 때에는 struct 키워드를 사용한다.
구조체형의 선언
struct 구조체형명
{
형명 식별자;
형명 식별자;
..........
};
구조체형은 블록 안에 변수와 같은 요소들을 함께 묶어 둔 것이다.
int형 변수 num과 double형 변수 gas가 선언되어 있다.
num은 차량 번호를, gas는 연료의 양을 표현하기 위해 사용한다.
구조체 변수 선언하기
구조체형을 선언하면 이는 새로운 형으로 인식된다.
따라서, 'Car'형 변수를 코드에서 선언할 수 있게 된 것이다. 선언 방법은 일반 변수와 같다.
구조체형명 구조체 변수명;
이렇게 선언한 변수 Car1은 CAR형 구조체의 값을 저장하는 변수가 된다.
멤버에 접근하기
구조체형 변수(구조체)를 선언하면, 그 구조체 안의 num과 gas에 실제 차량 번호 및 연료의 양을 저장할 수 있게 된다.
이 num, gas와 같은 변수들은 멤버(member)라고 부른다. 구조체의 멤버를 이용하기 위해서는 도트 연산자(.)라는 것을 사용해야 한다.
구조체 멤버에 접근하는 방법:
구조체변수명.멤버
예를 들어 구조체형 변수 Car1에는 다음과 같이 대입해서 값을 저장시킬 수 있다.
(차라는 물체 안에는, 여러 속성들이 있을 것이다. 예를 들어 가스량, 차 번호 등등...이런 것들을 표현해 주는 것이다.)
실제 코드를 통해 멤버에 접근해 보자.
이 코드에서는 구조체형 CAR을 선언하고 있다. 그 다음으로 CAR형 변수 Car1을 선언하고 있다.
그 후, 변수 Car1에 도트 연산자를 사용하여 구조체의 각 멤버에 접근하고 있다.
이처럼 구조체 변수에 도트 연산자를 사용하면 구조체의 멤버에 접근하여 값을 저장할 수 있다.
2. 구조체 응용하기
인수로 구조체 사용하기
구조체는 함수의 인수로도 사용할 수 있다.
앞선 게시글에서, 함수에 인수가 넘어갈 때, 기본적으로 인수의 값만 넘어간다는 사실을 확인했었다.
구조체를 인수로 사용하는 경우에도 '값' 이 넘어간다. 이는,
실인수 구조체의 멤버 값이 각각 복사된 후, 함수 본체에 전달된다.
는 뜻이다. 즉, 이 코드에 등장한 구조체 멤버인 num, gas의 값이 복사된 후, 함수 본체에 넘어가는 것이다.
구조체 포인터를 인수로 사용하기
구조체를 인수로 사용하면, 그 구조체의 각 멤버의 값이 복사되어 함수로 넘어간다. 그러나 멤버를 다수 포함하는 구조체를 인수로 사용할 경우에는 주의가 필요하다. 함수를 호출할 때마다 많은 수의 멤버가 복사되어야 하므로 함수 호출이 지연될 수 있기 때문이다.
따라서, 많은 수의 멤버를 포함하는 함수를 인수로 넘겨야 할 경우,
구조체 포인터를 인수로 넘기는 방법을 고려해야 한다.
즉, 구조체 변수의 주소만 함수에 넘기는 것이다. 구조체를 가리키는 포인터를 함수의 인수로 사용하면, 함수를 호출할 때 포인터만 넘기면 된다. 이러한 방법을 사용하면 큰 구조체를 인수로 사용할 경우에 속도 향상을 꾀할 수 있다. 또한 주소가 넘어가므로, 함수 안에서 원래 구조체 변수의 멤버 값을 변경시킬 수도 있다.
이렇게 사용하려면 구조체를 가리키는 포인터를 통해서 각 멤버에 접근하는 방법을 찾아야 한다.
이럴 때에는, 화살표 연산자(->)를 사용하면 편리하다.
구조체형 포인터로 구조체 멤버에 접근하기:
구조체형 포인터 -> 구조체 멤버
구조체를 가리키는 포인터를 인수로 받는 함수를 사용해보자.
show() 함수 안의 처리에 주목해 보자.
cout << "차량 번호는" << pC->num << " : 연료량은" << (*pC).gas << "입니다." << endl;
이 함수에는 포인터가 전달된다. 따라서 멤버에 접근할 때 도트 연산자(.) 대신 화살표 연산자(->)를 사용하고 있다. 실행 결과는 같다! (-> 대신에 *와 .을 이용해서 접근해도 좋다. 다만 꼭 포인터에 괄호를 붙여주어야 한다. 연산자 우선순위 때문에 괄호를 붙여주지 않을 경우 실행되지 않는다.)
구조체 레퍼런스를 인수로 사용하기
구조체 변수의 레퍼런스를 인수로 사용할 경우에도 같은 효과를 얻을 수 있다.
이 코드의 실행 결과는 위의 코드들과 같다. 그러나, 함수 안에서 멤버에 접근할 때, 화살표 연산자(->)가 아닌 도트 연산자를 사용한다는 점이 다르다. 구조체를 가리키는 포인터를 통해서 멤버에 접근할 때에만 화살표 연산자를 사용한다는 사실을 기억하자!
'C++ 코딩 > C++ 기초개념' 카테고리의 다른 글
C++ 반복자 Iterator (0) | 2022.11.06 |
---|---|
C++ Operator Overloading 연산자 오버로딩 (0) | 2022.09.26 |
STL 표준 템플릿 라이브러리 (Standard Template Library) (0) | 2022.04.01 |
<C++ 기초> 공용체 union (0) | 2021.03.18 |
<C++ 기초> 클래스 Class의 기본 - 맴버, 멤버함수, private, public, protect, 캡슐화 (1) | 2021.02.24 |
<C++ 기초> 식과 연산자, 연산자의 종류와 우선순위 (0) | 2021.02.23 |
<C++ 기초> 동적배열, sti vector, 멤버함수 (0) | 2021.02.18 |
<C++ 기초> typedef, 열거형 enum (0) | 2021.02.16 |