13. [C++] C++에서의 구조체
2024. 4. 12. 11:36ㆍ[C++]/C++ 언어 기초
구조체란?
- 연관있는 데이터를 하나로 묶으면, 프로그램 구현 및 관리를 용이하게 한다.
- 연관있는 데이터를 묶을 수 있는 문법적 장치
- 구조체의 예시) 자동차
- 소유주
- 연료량
- 현재 속도
struct Car{
char gamerID[ID_LEN];
int fuelGauge;
int curSpeed;
}
C++에서의 구조체 변수 선언
c++에서는 별도의 typedef 선언 없이도 다음과 같이 변수를 선언할 수 있다.
Car basicCar;
Car simpleCar;
Car run99={"run99", 100, 0};
RacingCar.cpp
#include <iostream>
using namespace std;
//구조체 Car와 관련된 정보 상수화
#define ID_LEN 20
#define MAX_SPD 200
#define FUEL_STEP 2
#define ACC_STEP 10
#define BRK_STEP 10
//구조체 Car
struct Car
{
char gamerID[ID_LEN]; // 소유자 ID
int fuelGauge; // 연료량
int curSpeed; // 현재속도
};
//차량 정보(const로 값 변경 불가하게 만든다)
void ShowCarState(const Car &car)
{
cout<<"소유자ID: "<<car.gamerID<<endl;
cout<<"연료량: "<<car.fuelGauge<<"%"<<endl;
cout<<"현재속도: "<<car.curSpeed<<"km/s"<<endl<<endl;
}
void Accel(Car &car)
{
if(car.fuelGauge<=0)
return;
else
car.fuelGauge-=FUEL_STEP;
if(car.curSpeed+ACC_STEP>=MAX_SPD)
{
car.curSpeed=MAX_SPD;
return;
}
car.curSpeed+=ACC_STEP;
}
void Break(Car &car)
{
if(car.curSpeed<BRK_STEP)
{
car.curSpeed=0;
return;
}
car.curSpeed-=BRK_STEP;
}
int main(void) {
Car run99 = {"run99", 100, 0};
Accel(run99);
Accel(run99);
ShowCarState(run99);
Break(run99);
ShowCarState(run99);
Car sped77 = {"sped77", 100, 0};
Accel(sped77);
Break(sped77);
ShowCarState(sped77);
return 0;
}
소유자ID: run99
연료량: 96%
현재속도: 20km/s
소유자ID: run99
연료량: 96%
현재속도: 10km/s
소유자ID: sped77
연료량: 98%
현재속도: 0km/s
- 위 함수들은 구조체 Car와 함께 부류를 형성해, Car와 관련된 데이터의 처리를 담당하는 함수들이다.
- 위 함수들은 구조체 Car에 종속적인 함수라 할 수 있지만, 전역함수의 형태를 띈다. 따라서 다른 영역에서 이 함수를 호출하는 실수를 범할수도 있다.
구조체 안에 함수 삽입
- 구조체 Car에 종속적인 함수를 구조체 안에 함께 묶는다.
- C++에서는 구조체 안에 함수를 삽입하는 것이 가능하다.
struct Car
{
char gamerID[ID_LEN]; // 소유자 ID
int fuelGauge; // 연료량
int curSpeed; // 현재속도
void ShowCarState()
{
cout<<"소유자ID: "<<gamerID<<endl;
cout<<"연료량: "<<fuelGauge<<"%"<<endl;
cout<<"현재속도: "<<curSpeed<<"km/s"<<endl<<endl;
}
void Accel()
{
if(fuelGauge<=0)
return;
else
fuelGauge-=FUEL_STEP;
if(curSpeed+ACC_STEP>=MAX_SPD)
{
curSpeed=MAX_SPD;
return;
}
curSpeed+=ACC_STEP;
}
void Break()
{
if(curSpeed<BRK_STEP)
{
curSpeed=0;
return;
}
curSpeed-=BRK_STEP;
}
};
구조체 밖과 구조체 안 함수 선언의 차이
void ShowCarState(const Car &car)
{
cout<<"소유자ID: "<<car.gamerID<<endl;
cout<<"연료량: "<<car.fuelGauge<<"%"<<endl;
cout<<"현재속도: "<<car.curSpeed<<"km/s"<<endl<<endl;
}
void ShowCarState()
{
cout<<"소유자ID: "<<gamerID<<endl;
cout<<"연료량: "<<fuelGauge<<"%"<<endl;
cout<<"현재속도: "<<curSpeed<<"km/s"<<endl<<endl;
}
- 함수가 구조체 밖에 있을 때에는 'car.'을 앞에 덧붙여 직접참조를 하고 있다.
- 함수를 구조체 안에 삽입하게 되면 구조체 내에 선언된 변수에 "직접접근"이 가능해져 'car.'을 붙힐 필요가 없어진다.
따라서 다음과 같이 구조체 변수를 각각 선언하면, 다음의 형태로 구조체 변수가 생성된다.
Car run99 = {"run99", 100, 0};
Car sped77 = {"sped77", 100, 0};
구조체 안에 enum 상수의 선언
#define ID_LEN 20
#define MAX_SPD 200
#define FUEL_STEP 2
#define ACC_STEP 10
#define BRK_STEP 10
- 이 상수들은 구조체 Car에게만 사용되는 상수들이다.
- 즉, 다른 영역에서는 사용되지 않으니 이 상수들도 구조체 내에 포함시키는 것이 좋다.
- 따라서 이러한 경우에는 열거형 enum을 이용해 구조체 내에서만 유효한 상수를 정의하면 된다.
struct Car
{
enum {
ID_LEN = 20,
MAX_SPD = 200,
FUEL_STEP = 2,
ACC_STEP = 10,
BRK_STEP = 10
};
char gamerID[CAR_CONST::ID_LEN]; // 소유자 ID
int fuelGauge; // 연료량
int curSpeed; // 현재속도
void ShowCarState(){ . . . . }
void Accel(){ . . . . }
void Break(){ . . . . }
};
- 상수, 함수를 전부 구조체 안에 넣었더니 구조체가 너무 커진다.
namespace CAR_CONST {
enum {
ID_LEN = 20,
MAX_SPD = 200,
FUEL_STEP = 2,
ACC_STEP = 10,
BRK_STEP = 10
};
}
- 이름 공간을 통해 구조체 밖으로 빼줄 수 있다.
함수는 외부로 뺄 수 있다.
C++의 구조체를 보는 순간, 다음 정보들이 쉽게 눈에 들어와야 코드 분석이 용이하다.
- 선언되어 있는 변수정보
- 정의되어 있는 함수정보
struct Car {
. . . . .
void ShowCarState();
void Accel();
. . . . .
};
void Car::ShowCarState() {
. . . . .
}
void Car::Accel() {
.
- 이와 같이 함수의 원형은 구조체에 두고, 함수의 정의를 밖으로 뺄 수 있다.
- 다만, 빼낸 다음 해당 함수가 어디에 정의되어 있는지 범위지정연산자(::)를 이용해 추가해줘야 한다.
#include <iostream>
using namespace std;
//상수는 namespace로 구분한다.
namespace CAR_CONST {
enum {
ID_LEN = 20,
MAX_SPD = 200,
FUEL_STEP = 2,
ACC_STEP = 10,
BRK_STEP = 10
};
}
//구조체 형태
struct Car
{
char gamerID[CAR_CONST::ID_LEN]; // 소유자 ID
int fuelGauge; // 연료량
int curSpeed; // 현재속도
void ShowCarState();
void Accel();
void Break();
};
//함수 정의
void Car::ShowCarState()
{
cout<<"소유자ID: "<<gamerID<<endl;
cout<<"연료량: "<<fuelGauge<<"%"<<endl;
cout<<"현재속도: "<<curSpeed<<"km/s"<<endl<<endl;
}
void Car::Accel()
{
if(fuelGauge<=0)
return;
else
fuelGauge-=CAR_CONST::FUEL_STEP;
if(curSpeed+CAR_CONST::ACC_STEP>=CAR_CONST::MAX_SPD)
{
curSpeed=CAR_CONST::MAX_SPD;
return;
}
curSpeed+=CAR_CONST::ACC_STEP;
}
void Car::Break()
{
if(curSpeed<CAR_CONST::BRK_STEP)
{
curSpeed=0;
return;
}
curSpeed-=CAR_CONST::BRK_STEP;
}
int main(void) {
Car run99 = {"run99", 100, 0};
run99.Accel();
run99.Accel();
run99.ShowCarState();
run99.Break();
run99.ShowCarState();
Car sped77 = {"sped77", 100, 0};
sped77.Accel();
sped77.Break();
sped77.ShowCarState();
return 0;
}
소유자ID: run99
연료량: 96%
현재속도: 20km/s
소유자ID: run99
연료량: 96%
현재속도: 10km/s
소유자ID: sped77
연료량: 98%
현재속도: 0km/s
문제
2차원 평면상에서의 좌표를 표현할 수 있는 구조체를 다음과 같이 정의하였다
struct Point
{
int xpos;
int ypos;
};
위의 구조체를 기반으로 다음의 함수를 정의하고자 한다(자세한 기능은 실행의 예를 통해서 확인)
void MovePos(int x, int y); //점의 좌표이동
void AddPoint(const Point &pos); //점의 좌표증가
void ShowPosition(); //현재 x, y 좌표정보 출력
int main(void)
{
Point pos1={12, 4};
Point pos2={20, 30};
pos1.MovePos(-7, 10);
pos1.ShowPosition(); //[5, 14] 출력
pos1.AddPoint(pos2);
pos1.ShowPosition(); //[25, 44] 출력
return 0;
}
내 풀이
#include "stdafx.h"
#include <iostream>
#include <cstring>
using namespace System;
using namespace std;
struct Point{
int xpos;
int ypos;
void MovePos(int x, int y){
xpos += x;
ypos += y;
};
void AddPoint(const Point &pos){
xpos += pos.xpos;
ypos += pos.ypos;
};
void ShowPosition(){
cout<<"["<<xpos<<","<<ypos<<"]"<<endl;
};
};
int main (void)
{
Point pos1 = {12, 4};
Point pos2 = {20, 30};
pos1.MovePos(-7, 10);
pos1.ShowPosition();
pos1.AddPoint(pos2);
pos1.ShowPosition();
return 0;
}
반응형
'[C++] > C++ 언어 기초' 카테고리의 다른 글
15. [C++] 객체지향 프로그래밍의 이해, 정보은닉, 캡슐화 (0) | 2024.04.12 |
---|---|
14. [C++] 클래스(Class)와 객체(Object) (1) | 2024.04.12 |
12. [C++] C++에서 C언어의 표준함수 호출하기 (0) | 2024.04.11 |
11. [C++] malloc & free를 대신하는 new & delete (0) | 2024.04.11 |
10. [C++] 참조자(Reference)와 함수2 (0) | 2024.04.11 |