프로그래밍/C++

[c++] 구조체, 구조체 배열, 구조체 포인터, 패딩바이트, typedef

FORHAPPy 2021. 9. 30. 02:40

구조체란

지금까지 썼던 자료형을 일반 자료형이라고 한다.

 

구조체는 사용자 정의 자료형에 속한다.

 

일반적인 생김새는 다음과 같다.

 

구조체 : 임의의 자료형 요소를 조합하여 다시만든 자료구조 이다.

구조체 이름앞의 xyz를 구조체 태그 라고 한다.

안에 선언된 걸 구조체 멤버라고 한다.

struct 구조체 명
{
 자료형들
}

 

 

 

이런식으로 안의 구조체 멤버들을 선언을 한다. 

여기서 주의해야 할 점은 char 형의 경우 char* 형으로 선언해주면 안되고,

배열의 크기를 명시해줘야지 에러가 나지 않는다. 

 

 

 

 

 

구조체 선언 및 초기화

 

아래와 같이 구조체 변수를 선언 및 초기화 할 수 있다.

각각의 자료형에 맞게 넣어 줘야 한다.

다 넣어 주지 못한 멤버는 자동으로 0으로 초기화 된다.

 

 

 

구조체 멤버

 

닷 연산자를 사용하여 구조체 각각의 멤버에 접근을 할 수 잇다.

 

 

 

구조체의 배열

구조체도 하나의 자료형이다. 사용자 정의 자료형이다.

따라서 배열이나 포인터로 똑같이 사용 가능하다.

여러개의 구조체들을 배열 형태로 만들면 다음과 같다.

배열을 만들 경우 배열의 인덱스를 이용하여 for을 돌리면 초기화가 가능하다.

Student tStuent[3] = { {},{},{} };
Student tStuent[3] = { };

메인 함수 내에서의 구조체 배열을 통해 멤버에 접근하려면 tStuent[i].szName 이과 같이 접근

 

 

 

 

매우 헷갈렸던 구조체 포인터 및 구조체 배열의 포인터 형식

 

--------------------------------------------------------- 구조체 포인터--------------------------------------------------------------
구조체를 매개변수의 인자로 넘겨 줄땐 PrintoutGrade ( &tStudent ); 이런식으로 주소값을 넘겨준다,
void PrintoutGrade(Student* pStudent) 매개변수로 받을때는 주소값 받는 포인터 형식으로 받는다.
일반 변수의 매개변수 전달 형식과 동일하다.
매개변수로 전달받은 구조체가 해당 함수 내에서 멤버에 접근을 하려면 일반변수와 마찬가지로 *(역참조 연산자)를 사용하여 멤버에  접근할 수 있다. 아래의 형식과 같다. 
(*pStudent).szName; == pStudent->szName; 괄호 대신 화살표 연산자를 사용하여 멤버에 접근할 수있다. 같은표현이다.
괄호를 꼭 써줘야 한다. .닷연산자가 역참조 연산자보다 연산자 우선순위에 있기 때문이다.
-------------------------------------------------------- 구조체 배열의 포인터-------------------------------------------------------
구조체배열을 매개변수의 인자로 넘겨 줄땐 PrintoutGrade ( tStudent ); 이런식으로 주소값을 넘겨준다,
배열의 이름은 곧 주솟값을 나타낸다.
void PrintoutGrade(Student* pStudent) 매개변수로 받을때는 주소값 받는 포인터 형식으로 받는다.
이는 일반 구조체 주소를 넘겨줄때랑 동일하다.
매개변수로 전달받은 구조체배열이 해당 함수 내에서 멤버에 접근을 하려면 Stduent[i].szName 이런식으로 접근하면 된다.
이렇게만 써줘도 배열이기 때문에  call by reference로 즉, 주소에 의한 참조가 되어진다.

 

 

typedef

아래와 같이 쓸 경우,
기존의 선언 방식인 struct xyz a; 이렇게 안쓰고
XYZ a; 이렇게만 써도 구조체의 자료형의 이름을 나타낼수 있다.

자료형을 재정의 하는 문법이다.

typedef struct xyz XYZ;

아래와 같이 쓸 경우 int형을 short로 바꿔 주면 기존 errorID를 썼던 곳의 자료형을 전부 바꿀 수 있다.  

typedef int errorID;

 

 

구조체의 크기 및 구조체 본인 가르키기

구조체의 크기는 멤머변수의 일반자료형 중에 가장 큰 자료형을 기준으로 결정 되어진다.

일반 자료형이 아닌 배열은 제외한다.

int int char 형이 멤버 변수로 있다고 하면 구조체의 메모리 크기는 12바이트 이다.

 

이렇게 되면 2바이트의 빈공간이 생기는데 이를 패딩바이트 남는다고 말한다.

그래서 남지 않게 자료형을 맞춰서 더 넣어 주기도 한다.

패딩바이트가 나중에 문제가 되는 경우도 간혹 있다. 쓰레기 값이 들어갈 수 있기 때문

 

구조체는 구조체본인의 크기를 알 수 없는 상태기 때문에 안에 본인이 멤버로 들어갈 수 없다. 

그러나 포인터 형식은 크기가 정해져 있기 떄문에 선언이 가능하다.

사진에서 보이는 1번의 형태는 선언 할 수 없다.