1. 구조체 목적
구조체는 관련 정보를 하나의 의미로 묶을 때 사용한다.
2. 구조체 사용 방법 (기본)
(1) 구조체 정의 및 변수 선언
구조체는 아래처럼 struct 키워드로 정의한다.
struct [구조체이름] {
자료형 멤버이름1;
자료형 멤버이름2;
...
};
////////////////////// 예시 ////////////////////////
struct member { // 구조체 이름 : member
char number[20]; // 구조체 멤버 1
char name[20]; // 구조체 멤버 2
int age; // 구조체 멤버 3
};
위처럼 정의한 구조체는 이후 int나 char형, unsigned int 등의 자료형처럼 struct [구조체이름] 형태로 자료형 자리에 붙여준다. 구조체를 변수로 선언하는 방법은 아래와 같다.
struct [구조체이름] [변수이름];
//////////////// 예시 ////////////////
struct member m1;
// "int i;" 와 비슷한 형태. int 대신 struct member라는 것이 들어갔다고 생각하자.
위처럼 선언한 구조체 변수에 접근하는 방법은 다음과 같다.
strcpy(m1.number, "202012345");
strcpy(m1.name, "몽구");
m1.age = 20;
// 온점(.)으로 구조체 멤버에 접근하여 값 할당
// 참고로 문자열은 할당이 안되므로 strcpy, strncpy, strlcpy 등을 이용하여 할당.
(2) typedef로 struct키워드 없이 구조체 선언하기
구조체 변수를 선언할 때 일일이 struct 키워드를 붙이는 것보다 typedef로 구조체를 정의하면서 별칭을 지어주자. 방법은 아래와 같다.
typedef struct [구조체이름] {
자료형 멤버1 이름;
자료형 멤버2 이름;
...
} 구조체별칭;
////////////////////// 예시 //////////////////////
typedef struct _member {
char number[20];
char name[20];
int age;
} member;
// 이후 struct _member [변수이름]이 아닌, member [변수이름]으로 사용 가능.
그리고 42서울 라피신 과정에서의 norminette 기준에 따르면 typedef로 구조체를 정의해줄 때 아래와 같은 규칙을 지켜줘야 한다.
typedef struct s_[구조체이름]
{
자료형 멤버1 이름;
자료형 멤버2 이름;
...
} t_[구조체별칭];
///////////////////// 예시 /////////////////////
typedef struct s_member
{
char number[20];
char name[20];
int age;
} t_member;
1) 구조체 이름 앞에는 s_ 를, 구조체 별칭의 이름 앞에는 t_ 를 붙여준다.
2) typedef와 struct 사이는 스페이스 하나로 채워준다.
3) typedef의 두 인자 (struct와 구조체이름) 사이에 탭을 써준다.
4) 구조체이름과 구조체 별칭의 정렬을 맞춰준다.
5) 멤버들의 이름의 정렬을 맞춰준다.
참고로 익명 구조체를 사용해도 되는데, norminette의 정렬 조건이 약간 달라진다.
typedef struct {
char number[20];
char name[20];
int age;
} t_member;
위와 같이 구조체 별칭이 멤버의 이름들과 정렬을 맞추워야 한다. 이외의 것들은 norminette 기준에 걸리는 건 없는 것 같다.
아무튼, 위처럼 typedef를 이용하여 구조체를 정의해줬다면 변수 선언은 기존의 방식이 아닌, 아래와 같은 방식으로 조금 더 간단하게 구조체 변수를 선언할 수 있다.
[구조체 별칭] [변수 이름];
//////////////// 예시 ////////////////
t_member m1;
3. 구조체 포인터
(1) 기본 사용 방법
struct [구조체이름] *포인터이름 = malloc(sizeof(struct [구조체이름]));
////////////////////////////// 예시 //////////////////////////////
#include <stdlib.h>
#include <string.h>
struct s_member {
char number[20];
char name[20];
int number;
};
int main(void)
{
struct s_member *p1 = malloc(sizeof(struct s_member));
// 화살표 연산자로 구조체 멤버에 접근하여 값 할당
strcpy(p1 -> number, "202012345");
strcpy(p1 -> name, "몽구");
p1 -> age = 20;
free(p1); // 동적 메모리 해제
return (0);
}
선언 방법
struct 키워드와 구조체 이름을 사용하여 구조체 포인터를 선언한다. 주의할 점은 포인터 변수니까 다른 자료형과 마찬가지로 애스터리스크(*)을 붙여준다. 또한, malloc을 해줄 때도 struct와 구조체 이름을 함께 써줘야 한다는 것을 명심하자.
주의할 점
포인터 이전에 대한 설명에서는 구조체 멤버에 접근할 때 온점(.)을 이용하여 접근했다. 하지만 구조체 포인터의 멤버에 접근할 때에는 화살표 연산자(->)를 사용해야 한다.
구조체 포인터에서 멤버에 접근할 때 온점을 사용하고 싶다면 아래와 같이 괄호와 역참조를 사용해줘야 한다.
p1 -> age; // 화살표 연산자로 멤버에 접근
(*p1).age; // 구조체 포인터를 역참조한 뒤, 온점(.)으로 멤버에 접근
(2) typedef를 응용한 구조체 포인터 사용 방법
구조체별칭 *포인터이름 = malloc(sizeof(구조체별칭));
////////////////////////////// 예시 //////////////////////////////
#include <stdlib.h>
#include <string.h>
typedef struct {
char number[20];
char name[20];
int number;
} t_member;
int main(void)
{
t_member *p1 = malloc(sizeof(t_member));
// 화살표 연산자로 구조체 멤버에 접근하여 값 할당
strcpy(p1 -> number, "202012345");
strcpy(p1 -> name, "몽구");
p1 -> age = 20;
free(p1); // 동적 메모리 해제
return (0);
}
기본 사용법에서 언급한 것과 크게 다르지 않은 로직이다. 유일한 차이점은 struct [구조체이름] 이 들어갈 자리에 [구조체별칭] 만 들어갔다는 것이다.
출처 : 코딩 도장 구조체 파트 (챕터 48, 49)
'Dev > 42Seoul' 카테고리의 다른 글
open, read, close 함수 정리 (0) | 2020.07.18 |
---|---|
헤더 파일 관련 정리 (0) | 2020.07.16 |