Menu

C++ 구조체(struct): 관련 데이터를 하나의 타입으로 묶기

C++ 구조체 설명. 관련 변수를 하나의 타입으로 묶는 방법, 구조체 객체를 선언하고 초기화하는 방법, 구조체에 멤버 함수와 생성자를 부여하는 방법, 그리고 struct가 class와 실제로 어떻게 다른지 알아봅니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

데이터를 함께 묶는 이유

지금까지 모든 변수는 각자 따로 존재했습니다. 여기 int 하나, 저기 string 하나. 하지만 실제 프로그램은 여러 조각으로 이루어진 것들을 다룹니다. 점에는 xy가 있고, 학생에게는 이름, 나이, GPA가 있습니다. 이런 것들을 흩어진 별개의 변수로 주고받는 것은 오류가 나기 쉽습니다. 아무것도 그것들을 서로 묶어주지 않으며, 셋 모두가 필요한 함수는 세 개의 매개변수를 모두 받아야 합니다.

구조체가 이 문제를 해결합니다. 구조체는 관련 변수들 — 그 멤버들 — 을 하나의 단위로 묶는 새로운 타입을 정의합니다. 일단 정의하면, 그 묶음 전체를 저장하고 복사하고 함수에 전달할 수 있는 하나의 값으로 다룹니다.

각 멤버에는 점 연산자로 접근합니다(s.name, s.age). 구조체 정의의 닫는 } 뒤의 세미콜론은 필수입니다. 이를 빼먹는 것은 C++ 초보자가 가장 흔히 겪는 컴파일 오류 중 하나입니다.

구조체 초기화하기

각 필드를 직접 대입하는 방식도 동작하지만, 장황하고 멤버를 빠뜨리기 쉽습니다. 더 깔끔한 방법은 집합체 초기화입니다. 멤버가 선언된 순서대로 값을 중괄호 안에 나열합니다.

빈 기본값에 주의하세요. Point p;(중괄호 없음)는 내장 타입 멤버가 자동으로 0이 되지 않기 때문에 xy쓰레기 값으로 남깁니다. Point p{};는 이들을 값 초기화하여 0으로 만듭니다. 중괄호를 사용하세요. 정의에 기본값을 직접 새겨 넣을 수도 있어서, Point p;조차 깨끗한 상태로 시작합니다.

함수 매개변수로서의 구조체

구조체는 하나의 값이므로, 함수는 세 개 대신 한 개의 매개변수를 받을 수 있습니다. 다만 구조체를 값으로 전달하면 모든 멤버가 복사된다는 점을 기억하세요. int 몇 개보다 큰 것이라면, 복사를 건너뛰기 위해 const 참조로 전달하세요. 참조 페이지에서 본 것과 같은 규칙입니다.

함수에서 구조체 전체를 반환하는 것은 여러 값을 한 번에 돌려주는 관용적인 방법으로, 여러 개의 출력 참조를 다루는 것보다 훨씬 깔끔합니다.

멤버 함수와 생성자 추가하기

구조체는 데이터에만 국한되지 않습니다. 자신의 멤버를 다루는 멤버 함수와, 객체가 생성되는 순간 그것을 초기화하는 생성자를 가질 수 있습니다. 바로 이 지점에서 구조체는 동작을 갖춘 작은 객체처럼 보이기 시작합니다.

멤버 함수 안에서는 멤버에 이름으로 접근합니다(width, height). 이들은 객체의 복사본을 가리킵니다. area() const로 표시하면 그 함수가 객체를 읽기만 한다고 컴파일러에 알리며, 덕분에 const Rectangle 값에 대해서도 호출할 수 있습니다. 생성자는 그 : width(w) 초기화 리스트 문법을 포함해 그 자체로 하나의 주제입니다. 생성자 페이지에서 깊이 다룹니다.

struct vs. class: 진짜 차이

"구조체는 데이터용, 클래스는 객체용"이라는 말을 들어본 적이 있을 것입니다. 그것은 관례이지 언어 규칙이 아닙니다. C++에서 structclass는 거의 같은 것이며, 유일하게 내장된 차이는 기본 접근 수준입니다.

struct S {
    int x;        // 기본적으로 public
};

class C {
    int x;        // 기본적으로 private
};

struct의 멤버는 따로 표시하지 않으면 public이고, class의 멤버는 private로 시작합니다. 그것이 전부입니다. 둘 다 생성자, 멤버 함수, 상속, 그리고 그 밖의 모든 것을 가질 수 있습니다. 멤버를 숨기기 위해 구조체에 명시적인 접근 지정자를 추가할 수도 있습니다.

실용적인 교훈은 이렇습니다. 모든 필드를 자유롭게 다뤄도 되는 투명한 데이터 묶음(Point, Color, 설정 레코드)에는 struct를 사용하고, 내부 상태를 공개 인터페이스 뒤로 보호하고 싶을 때는 class를 사용하세요. 컴파일러는 둘을 똑같이 취급합니다. 키워드는 그저 당신의 의도를 알릴 뿐입니다.

구조체의 배열과 벡터

구조체는 평범한 타입이므로, 여러 개를 배열이나 벡터에 담아 다른 값과 똑같이 반복할 수 있습니다.

중첩된 중괄호에 주목하세요. 각 {"Keyboard", 49.99}는 하나의 Product를 집합체 초기화하고, 바깥쪽 중괄호는 벡터를 구성합니다. 범위 기반 루프에서 const Product&를 사용하면 반복마다 각 구조체를 복사하지 않습니다. &를 빼면 모든 요소를 불필요하게 복제하게 됩니다.

다음: 열거형(Enums)

구조체로는 여러 값을 함께 묶어 하나의 타입을 만들 수 있습니다. 다음 장은 반대 방향으로 갑니다. 열거형(enum)은 작은 이름 붙은 집합 중에서 정확히 하나의 값을 가질 수 있는 타입을 정의합니다. Color::Red, Direction::North, 또는 상태 기계의 상태 같은 것에 안성맞춤입니다. enum class가 지금 만들고 있는 구조체 및 클래스와 자연스럽게 어울리는, 읽기 쉽고 타입 안전한 상수를 어떻게 제공하는지 보게 될 것입니다.

자주 묻는 질문

C++에서 구조체(struct)란 무엇인가요?

struct는 관련된 여러 변수(멤버라고 부릅니다)를 하나의 이름 아래에 묶는 사용자 정의 타입입니다. string name, int age, double gpa 변수를 따로따로 다루는 대신, 이들을 하나의 Student 타입으로 묶어 그 한 개의 객체를 주고받습니다. 구조체는 멤버 함수와 생성자도 가질 수 있습니다. 현대 C++에서 구조체는 멤버가 기본적으로 public인 어엿한 클래스입니다.

C++에서 struct와 class의 차이는 무엇인가요?

기술적으로는 기본 접근 수준뿐입니다. struct의 멤버는 따로 지정하지 않으면 public이고, class의 멤버는 기본적으로 private입니다. 상속에서도 마찬가지입니다. 그 외 모든 것(생성자, 멤버 함수, 메서드, 상속)은 동일하게 동작합니다. 관례적으로 프로그래머는 단순한 데이터 묶음에는 struct를, 불변 조건과 숨겨진 내부를 가진 타입에는 class를 사용합니다.

C++에서 구조체를 어떻게 초기화하나요?

가장 간단한 방법은 멤버 순서대로 중괄호에 값을 나열하는 **집합체 초기화(aggregate initialization)**입니다: Point p{3, 4};. 점 연산자로 각 필드를 직접 대입하거나(p.x = 3;), 정의에서 멤버에 기본값을 줄 수도 있고(int x = 0;), 구조체가 스스로 설정하도록 생성자를 작성할 수도 있습니다. 중괄호 초기화는 필드를 조용히 초기화되지 않은 채로 남기지 않기 때문에 권장됩니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기