2024. 3. 8. 21:38ㆍProgramming Language/C++
아래 링크 클릭 시 해당 본문으로 이동
구조체(Structure) - C++ vs. C
1. C++ 문법
• 사용자 정의 자료형(UDDT : User Defined Data Type)이라고도 한다.
• 내 맘대로 자료형을 만드는 것 (나만의 자료형)
• 기본 문법이 아니기 때문에 내가 짠 코드에서만 적용된다.
언어에서 기본으로 제공해 주는 자료형 외에 내 방식대로 새로운 자료형을 만들고 싶을 때 사용한다.
// typedef : 타입 재정의
typedef struct 구조체명
{
구조체 멤버; // 멤버 : 구성 요소
} 구조체변수명; // 세미콜론 꼭 쓰기!
구조체도 모듈화가 가능하다.
더 큰 자료형 안에 내가 만든 구조체가 그것의 부분으로 들어가서 점점 확장해 나갈 수 있다.
typedef struct _tagMYST
{
int a;
float b;
} MYST;
typedef struct _tagBig
{
MYST m; // 구조체 변수 MYST의 멤버 m을 _tagBig 안에서 선언했다.
int d;
char e;
} BIG;
※ 구조체 안에 변수를 선언
// MYST => int형 + float형
typedef struct _tagMYST
{
int a; // int 파트 이름 : a
float b; // float 파트 이름 : b
} MYST;
'int형 변수 a'처럼 변수를 선언한 것이 아니다.
단지 이름을 부여한 것으로, 내가 만든 자료형인 `MYST`에 `int` 파트와 `float` 파트가 있다는 의미이다.
즉, 구조체를 선언한 상태에서는 단순히 데이터 타입을 정의한 것이므로 메모리가 할당되지 않고 변수가 생성되지 않는다.
구조체 변수를 선언해서 사용해야 변수가 생성되고 메모리가 할당된다.
구조체 변수 선언하는 법
• `구조체변수이름 변수명;`
일반 변수를 선언하는 방식과 똑같다.
• 선언한 자료형들을 묶어서 만들었기 때문에 해당 자료형들의 크기를 합하면 구조체의 크기이다.
▷ 예시
typedef struct _tagMYST
{
int a;
float b;
} MYST;
int main()
{
// 구조체 변수 선언
MYST c; // c의 크기 = 8byte (int형 4byte + float형 4byte)
// 구조체 크기 확인
int iSize = sizeof(MYST); // 8
return 0;
}
• sizeof()
선언한 변수나 특정 자료형의 크기가 어느 정도인지 알려주는 함수
각각의 파트에 세부적으로 접근하고 싶을 때
• `선언한변수.파트이름`
내가 만든 자료형으로 선언한 변수 + 온점(.) + 내가 만든 자료형에서 접근하고 싶은 파트 이름
typedef struct _tagMYST
{
int a;
float b;
} MYST;
int main()
{
MYST c;
c.a = 5; // int 파트 접근
c.b = 3.62f; // float 파트 접근
return 0;
}
`c.`을 입력하면 `a`와 `b`로 접근할 수 있다는 것을 알 수 있다.
기본 자료형 int를 구조체로 정의 및 선언했을 때
typedef int INT;
int main()
{
INT a; // int
}
컴파일러는 `INT`를 int로 받아들인다.
즉, 기본 자료형을 `typedef`로 정의하면 컴파일러는 해당 기본 자료형으로 받아들인다.
2. C 문법
C 문법으로 변경하는 법
[프로젝트] - [`프로젝트명` 속성] - [구성 속성] - [C/C++] - [고급] - '컴파일 옵션'에서 'C 코드로 컴파일' 선택
▷ C++ 문법으로 작성한 구조체
typedef struct _tagMYST
{
int a;
float b;
} MYST;
typedef struct _tagBig
{
MYST m;
int d;
char e;
} BIG;
typedef int INT;
int main()
{
_tagMYST m; // C 문법에서는 오류
return 0;
}
구조체 이름인 `_tagMYST`을 이용해 변수를 선언하면 C 문법에서는 오류가 발생한다.
구조체 초기화 하는 법
배열 초기화 방법과 비슷하다.
• `구조체변수명 변수 = { 값1, 값2, ... };`
typedef struct _tagMYST
{
int a;
float b;
} MYST;
int main()
{
// 구조체 초기화
MYST c = { 30, 5.62f }; // 구조체 초기값 => int 파트 a = 30, float 파트 b = 5.62f
return 0;
}
Q. c.b의 경우 5.62가 아닌 5.61999989로 표시되는데, 그 이유는?
A. 실수는 그 숫자를 정확하게 표현하는 것이 아니라 부동 소수점으로 최대한 비슷한 값을 찾는다.
때문에 실제 메모리 값에서 약간의 오차가 있을 수 있다.
C 문법으로 구조체 만드는 법
C 문법에서는 `struct`로 구조체라는 것을 명시해줘야 한다.
태그명은 `struct` 뒤에 쓴다.
struct 태그명
{
구조체 멤버;
}; // 세미콜론 꼭 쓰기!
C 문법으로 구조체 선언하면 불편한 점
• 사용자가 직접 정의한 자료형은 매번 앞에 `struct`를 붙여서 구조체를 정확히 명시해줘야 한다.
• 자료형을 지칭하는 데 있어서 길이가 길어진다.
struct NewStruct
{
int i;
double d;
};
int main()
{
struct NewStruct ns; // struct 안 쓰면 오류
}
C++에서는 `typedef struct`로 자료형을 만들면 선언할 때 굳이 `struct`를 앞에 붙이지 않아도 된다.
다시 C++문법으로 변경하자.
C 문법으로 작성한 구조체는 C++ 문법에서도 오류가 뜨지 않는다.
typedef struct _tagMYST
{
int a;
float b;
};
typedef struct _tagBig
{
MYST m;
int d;
char e;
};
typedef struct NewStruct
{
int i;
double d;
};
typedef int INT;
int main()
{
// C 문법이지만 오류가 발생하지 않는다.
struct _tagMYST m;
struct NewStruct ns;
return 0;
}
구조체 포인터
• `구조체변수명*`
구조체도 자료형이기 때문에 포인터로 만들 수 있다.
typedef struct _tagMYST
{
int i;
float f;
} MYST;
int main()
{
MYST s = {};
MYST* pST = &s; // 포인터 변수 pST에 s의 주소 저장
pST + 1; // 실제로는 8이 더해진다.
return 0;
}
`pST`는 `s`의 주소를 저장하고, 주소로 접근하면 int형 멤버 `i`와 `float`형 멤버 `f`가 존재한다.
총 8byte이기 때문에 `pST`에 1을 더하면 실제로는 8이 더해진다.
`(*pST).i`처럼 세부적인 파트로 접근할 수 있다.
구조체 포인터 타입에서 매번 지칭해야 되는 번거로움이 있어서 역참조 이후에 파트를 지칭하는 것을 `->`로 한 번에 표현할 수 있다.
typedef struct _tagMYST
{
int i;
float f;
} MYST;
int main()
{
MYST m = {};
MYST* pST = &s;
*pST; // s의 주소로 접근 (역참조)
//(*pST).i = 50;
pST->i = 50;
//(*pST).f = 10.5f;
pST->f = 10.5f;
return 0;
}
구조체는 기본 자료형과 다르게 멤버를 여러 개 가질 수 있다.
포인터로 구조체 타입을 지칭할 경우 역참조한 이후에 멤버를 선택해줘야 한다.
'Programming Language > C++' 카테고리의 다른 글
[C++] 분할 구현, 분할 구현 문제점 (0) | 2024.03.11 |
---|---|
[C++] 컴파일 과정 (0) | 2024.03.08 |
[C++] 배열(Array) (0) | 2024.03.04 |
[C++] 호출 스택, 반복문 vs. 재귀함수[팩토리얼, 피보나치 수열], 꼬리 재귀 (0) | 2024.03.04 |
[C++] 반복문, 반복문 탈출 방법 (0) | 2024.03.03 |