[기술 질문] #5_struct, 구조체
C++의 구조체에 대해 알아보겠습니다.
Overview
- 개념
- 배열과 구조체
- 공용체
- 패딩
#1 개념
1. 구조체?
struct MyStruct
{
int IntVal;
float FloatVal;
long LongVal;
string Str;
};
- 구조체는 논리적으로 관련이 있는 항목들을 하나의 자료형으로 묶기 위해 사용됩니다.
- 객체의 데이터 멤버처럼, 구조체의 각 멤버들은 "."를 통해 접근이 가능하며, 포인터를 활용할 수도 있습니다.
2. 주의할 점?
- 구조체 변수 사이에 비교 연산자를 사용할 수 없습니다.
- 구조체 자신의 멤버로 구조체 자신을 사용할 수 없습니다.
- 구조체 선언에서 멤버 변수를 초기화할 수 없습니다.
3. 코드
#include <iostream>
using namespace std;
struct Point {
int x;
int y;
};
// 1. Call-by-Value, 값에 의한 전달
void PrintCooridnate1(struct Point p)
{
cout << "x : ";
cout << p.x << endl;
cout << "y : ";
cout << p.y << endl;
}
// 2. Call-by-Address, 주소에 의한 전달
void PrintCoordinate2(struct Point* p)
{
cout << "x : ";
cout << p->x << endl;
cout << "y : ";
cout << p->y << endl;
}
int main()
{
struct Point MyPoint = { 10, 2 };
PrintCooridnate1(MyPoint);
PrintCoordinate2(&MyPoint);
}
#2 배열과 구조체
1. 차이점
- 구조체는 다양한 자료형의 변수들을 담고 있지만, 배열은 동일한 자료형들만 담고 있습니다.
- 구조체는 다양한 자료형들을 묶어 하나의 자료형을 선언하는 것이며, 배열은 변수를 선언하는 것입니다.
#3 공용체
1. 개념
- 공용체는 union 키워드를 통해 선언하며, 모든 멤버 변수가 하나의 메모리 공간을 공유합니다.
- 모든 멤버 변수가 하나의 메모리 공간을 공유하기 때문에, 한 번에 하나의 멤버 변수만 사용 가능합니다.
2. 코드
#include <iostream>
using namespace std;
union MyUnion {
int IntVal;
float FloatVal;
double DoubleVal;
char CharVal;
};
int main()
{
MyUnion un;
un.IntVal = 3;
cout << un.IntVal << endl; // 3 출력
un.FloatVal = 3.3f;
cout << un.IntVal << endl; // 쓰레기 값 출력
cout << un.FloatVal << endl; // 3.3 출력
}
#4 패딩
1. 개념
- 중간에 빈 공간(패딩)을 의도적으로 만들어, CPU가 접근하기 쉬운 메모리 위치에 구조체 필드를 배치합니다.
- 이러한 방식은 추가적인 메모리 공간을 필요로 하지만, 성능 향상을 보장합니다.
- 아래 예제를 통해 자세한 내용을 살펴보겠습니다.
2. 예제
struct Box{
char c;
long long ll;
};
- 32bit 컴퓨터는 구조체의 "ll" 변수에 접근하기 위해 메모리에 3번 접근합니다.
- 64bit 컴퓨터는 구조체의 "ll" 변수에 접근하기 위해 메모리에 2번 접근합니다.
- Padding 비트가 존재하지 않기 때문에, 불필요한 추가적인 메모리 접근이 불가피합니다.
- 패딩 값을 넣어준다면, 32bit의 경우 "ll" 변수에 접근하기 위해, 메모리에 2번 접근합니다. (4byte packing)
- 패딩 값을 넣어준다면, 64bit의 경우 "ll" 변수에 접근하기 위해, 메모리에 1번 접근합니다. (8byte packing)
- 패딩을 통해 미리 구조체의 메모리를 정렬해 놓으면, 불필요한 추가적인 메모리 접근을 방지할 수 있습니다!
3. 문제점?
- 서로 다른 컴파일러, 혹은 운영체제는 메모리를 읽는 방식이 다르기 때문에, 패딩 비트 때문에 구조체 필드를 원래의 것과 다르게 읽을 수 있습니다.
- 따라서, 아래의 코드를 통해 2가지 패딩 바이트 삽입 방법을 살펴보겠습니다.
4. 코드
#include <iostream>
using namespace std;
// 1. #pragma pack(puch, 1) 활용
#pragma pack(push, 1)
struct Box {
char c;
long long ll;
};
#pragma pack(pop)
// 2. 사용자 정의 패딩 비트
struct Box2 {
char c;
char b[7]; // Dummy 값 삽입
long long ll;
};
'언어 > 기술 질문' 카테고리의 다른 글
[기술 질문]#9_객체 지향 프로그래밍(OOP) (0) | 2023.02.12 |
---|---|
[기술 질문]#6_동적 할당 (0) | 2023.01.27 |
[기술 질문]#4_#define, 매크로 (0) | 2023.01.08 |
[기술 질문]#3_const 키워드 (0) | 2023.01.07 |
[기술 질문] #2_auto 키워드, extern 키워드 (0) | 2023.01.01 |