최근 수정 시각 : 2024-10-26 02:05:10

구조체


파일:나무위키+유도.png  
은(는) 여기로 연결됩니다.
퍼니싱 그레이 레이븐의 구조체에 대한 내용은 퍼니싱 그레이 레이븐/구조체 문서
번 문단을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
참고하십시오.
프로그래밍 언어 문법
{{{#!wiki style="margin: -16px -11px; word-break: keep-all" <colbgcolor=#0095c7><colcolor=#fff,#000> 언어 문법 C( 포인터 · 구조체 · size_t) · C++( 자료형 · 클래스 · 이름공간 · 상수 표현식 · 특성) · C# · Java · Python( 함수 · 모듈) · Kotlin · MATLAB · SQL · PHP · JavaScript · Haskell( 모나드)
마크업 문법 HTML · CSS
개념과 용어 함수( 인라인 함수 · 고차 함수 · 람다식) · 리터럴 · 상속 · 예외 · 조건문 · 참조에 의한 호출 · eval
기타 == · === · deprecated · NaN · null · undefined · 배커스-나우르 표기법
프로그래밍 언어 예제 · 목록 · 분류 }}}

1. 개요2. 구조체의 정렬3. 다른 언어에서

1. 개요

C언어에서 구조화된 데이터를 처리할때 사용한다. 쉽게 말하면, 구조체란 하나 이상의 변수를 묶어서 새로운 자료형을 정의하는 도구이다. 구조체를 정의할 때에는 struct를 사용한다. 이 구조체 개념은 객체 지향 언어의 탄생에 지대한 공을 세웠다.

아마 구조체에 대해 찾아볼 정도면 이미 int(정수형), float, double(이상 실수형), char(문자형) 등 여러 가지의 자료형(Data Type)을 만나 보았을 것이다. 이러한 자료형들은 이미 C안에 내장되어있는 원시 자료형(Primitive Data Type)으로 사용자가 직접 건드릴 수 없다. 하지만 구조체가 그와 비슷한 일을 하게 해준다. 바로 새로운 데이터 타입을 우리가 직접 정의할 수 있게 해 주는 것이다. 사용자가 직접 정의한 자료형을 '사용자 정의 자료형(User Defined Data Type)'이라고 부른다.

마우스 포인터를 예로 들자면, 마우스 포인터는 2차원 내에서 움직이기 때문에 x축 좌표 요소와 y축 좌표 요소가 이루는 값으로 위치를 표현할 수 있다. 마우스가 움직일 때마다 이 값은 변하며, 두 요소 중 하나라도 없어지게 되면 마우스의 위치를 의미하던 이 값은 의미를 잃게 된다. 이 요소와 값은 다음과 같이 선언할 수 있다.(자료형과 변수명은 사용자에 따라, 상황에 따라 달라질 수는 있다.)
#!syntax cpp
int Xposition; // 정수형 Xposition 선언
int Yposition; // 정수형 Yposition 선언
보다시피 2개의 변수를 따로 선언했다.
#!syntax cpp
struct Position //Position형 구조체 선언
{
   int Xposition; //정수형 Xposition 선언
   int Yposition; //정수형 Yposition 선언
};
이것으로 우리는 Position형 데이터 타입을 선언하였다. 다른 int형, float형, double형의 자료형처럼 Position 형 자료형이 생긴 것이다. 사용법을 보면 금방 익숙해질 것이다.
#!syntax cpp
struct Position pos1, pos2; //Position 자료형을 가진 변수 pos1, pos2를 선언하였습니다.
pos1.Xposition=10; //Position형 pos1변수의 Xposition의 값을 10으로 초기화하였습니다.
pos1.Yposition=34; //Position형 pos1변수의 Yposition의 값을 34으로 초기화하였습니다.
pos2.Xposition=23; //Position형 pos2변수의 Xposition의 값을 23으로 초기화하였습니다.
pos2.Yposition=7; //Position형 pos2변수의 Yposition의 값을 7으로 초기화하였습니다.
첫 선언부를 보면 일반 변수를 선언하는 것처럼 자료형을 한 번만 언급하고 ,를 이용해 연속적으로 선언이 가능한 모습을 볼 수 있다. 이것이 가능한 이유는 엄연한 하나의 자료형으로서 변수를 선언하기 때문이다.

구조체 내부의 값에 접근하기 위해서는 .을 이용한다. pos1, pos2 변수의 값을 .를 이용해 접근한 뒤 임의의 값으로 초기화하는 것을 볼 수 있다.

2. 구조체의 정렬

컴퓨터 메모리는 2의 배수의 크기로 관리된다. 2020년대에 주로 쓰이는 컴퓨터는 64비트 기반으로, 메모리를 읽고 쓰는 기본 단위는 8바이트이다.
그런데 구조체에는 다양한 메모리 크기의 변수가 포함될 수 있다. 다음의 구조체를 그저 그대로 메모리에 넣으면 어떻게 될까?
#!syntax cpp
struct Complex {
   char X;
   long long Y;
   long long Z;
}
이 구조체는 17바이트를 차지하므로 64비트 컴퓨터가 이 구조체를 전부 읽어들일 때는 세 번 읽어들이면 된다. 그런데, X가 1바이트를 밀어버린 탓에 Y와 Z는 8바이트 경계를 침범하게 되고 따라서 Y 또는 Z를 단독으로 읽을 때는 메모리를 두 번 읽어들여야 한다.

이 문제를 해결하기 위해, C는 구조체 멤버가 '자기 정렬 크기의 배수가 되는 자리'에 들어가는 것으로 정했다. 여기서 정렬 크기란 컴파일러가 정한 최고 정렬 크기[1] 또는 별도 명령어로 정한 최고 정렬 크기와 해당 멤버의 크기 중 작은 것이다. 컴파일러가 최고 정렬 크기를 8바이트 이상으로 정한 환경에서, long long은 0, 8, 16,... 등 8의 배수가 되는 자리에 들어가야 한다. 또한 구조체의 전체 크기는 가장 크기가 큰 멤버의 정렬 크기의 배수가 된다.

위의 구조체를 정렬하면, X 다음에는 7바이트의 패딩이 들어가고, 그 다음 Y, Z가 들어가서 총 24바이트 크기의 구조체가 된다.

3. 다른 언어에서

C++에서는 기본 접근 제어자가 다른 것 말고는 클래스와 동일하다. 구조체는 public, 클래스는 private, 상속 접근 제한자의 경우도 마찬가지. 굳이 차이를 꼽으라면 C에서도 돌아간다는 정도말고는 생성자나 멤버 함수라던지 상속이라던지 클래스에서 돌아가는 모든것이 구조체에서도 돌아간다. 심지어 경고를 띄우긴 하지만 class-struct 사이의 상속도 가능하다.

Java에는 구조체가 따로 없고 그냥 클래스를 사용한다.

C#의 경우는 클래스와 거의 비슷한 구조체(struct 키워드)가 있으나 다른점이 몇가지 있다.
  1. 참조에 의한 호출이 기본인 클래스와 달리 값에 의한 전달
  2. 생성자 기능 일부
    • 매개변수 없는 생성자가 암묵적으로 존재(구조체 필드들의 모든 비트를 0으로 초기화), 이를 재정의 하는 것은 불가능
    • 매개변수 있는 생성자를 직접 정의하는 경우 해당 생성자에서 모든 필드를 명시적으로 배정해야 함
  3. 상속 미지원 (인터페이스의 구현은 가능), 따라서 상속과 관련된 키워드들도 사용 불가
  4. 필드 초기화 미지원
  5. 소멸자 미지원


[1] Visual C++를 예로 들면 x64에서는 16바이트, x86/ARM/ARM64에서는 8바이트를 기본으로 설정한다.