학습 목표
! 본 내용은 검토 전 포스트 입니다. 부정학한 내용이 있을 수 있으니 양해바랍니다.
- 구조체의 사용 방법을 학습한다.
1. 구조체
구조체는 관련된 변수를 하나의 자료형으로 만들어 보관하는 것이다. 예를 들어 사람의 정보인 이름, 나이, 학과를 저장할 때 모두 다른 변수로 저장해도 되지만 묶어서 저장하면 더욱 효율적이다. 아래 코드는 구조체를 선언하는 방법이다. 구조체 명으로는 흔히 Pascal case로 맨앞글자만 대문자로 작성한다.
struct 구조체명 {
자료형 변수명;
...
자료형 변수명;
};
struct Info {
char name[20];
int age;
char major[20];
};
2. 구조체 변수 선언
만들어진 구조체 사용하여 변수를 선언해보겠다. 아래 코드에서는 struct Info가 자료형이고 이에 해당하는 person 구조체 변수를 생성하였다. name, age, major 변수는 person 변수의 멤버(member)라고 한다.
#include <stdio.h>
struct Info {
char name[20];
int age;
char major[20];
};
int main(void) {
struct Info person;
return 0;
}
구조체를 선언함과 동시에 전역 변수를 생성 할 수 있다. 구조체 아래에 원하는 변수명을 , 로 구분하여 작성해주면 된다.
#include <stdio.h>
struct Info {
char name[20];
int age;
char major[20];
} person;
#include <stdio.h>
struct Info {
char name[20];
int age;
char major[20];
} person1, person2;
2.1. 자료형 별칭
typedef는 기존의 자료형에 새로운 별칭을 붙여주는 것입니다. 아래 코드는 int 자료형을 INT로 별칭을 붙여주고 변수를 생성하는 코드입니다.
#include <stdio.h>
typedef int INT;
int main(void) {
INT age = 25;
printf("%d", age);
return 0;
}
typedef를 활용해 긴 구조체 자료형을 줄일 수 도 있습니다. 보통 상수처럼 모든 문자를 대문자로 작성하고 단어와 단어 사이에는 언더바로 구분합니다.
#include <stdio.h>
struct Info {
char name[20];
int age;
char major[20];
};
typedef struct Info INFO;
int main(void) {
INFO person;
return 0;
}
이를 더욱 줄여서 아래 코드와 같이 구조체 선언과 동시에 자료형을 축약할 수 있습니다. 구조체 하단의 INFO는 변수가 아닌 자료형입니다.
#include <stdio.h>
typedef struct {
char name[20];
int age;
char major[20];
} INFO;
int main(void) {
INFO person;
return 0;
}
3. 구조체 변수 초기화
구조체 변수를 초기화 하는 방법에는 2가지가 있다. 변수 선언과 동시에 초기화 하는 것이고, 두번째는 변수 선언 후 초기화 하는 것이다.
3.1. 선언과 동시에 초기화
선언과 동시에 초기화 하는 방법은 아래 코드와 같이 중괄호 사이에 값을 차례 대로 넣어주면 된다.
#include <stdio.h>
typedef struct {
char name[20];
int age;
char major[20];
} INFO;
int main(void) {
INFO person = {"daehun", "25", "SW"};
return 0;
}
만약 중괄호를 비워놓거나 일부 멤버의 값만 넣었을 경우 나머지 멤버에는 0이 들어가게 된다. 마찬가지로 배열의 모든 공간에도 0이 들어간다.
#include <stdio.h>
typedef struct {
char name[20];
int age;
char major[20];
} INFO;
int main(void) {
INFO person = {};
return 0;
}
3.2. 선언 후 초기화
선언 후 초기화는 변수명.맴버명 에 대입연산을 하여 초기화 한다. 다만 문자열의 경우 strcpy 같은 문자열 함수를 사용하여 초기화하여야한다. 대입연산을 통해 초기화하지 않은 변수들은 쓰레기 값이 들어간다.
#include <stdio.h>
#include <string.h>
typedef struct {
char name[20];
int age;
char major[20];
} INFO;
int main(void) {
INFO person;
strcpy(person.name, "daehun");
person.age = 25;
strcpy(person.major, "SW");
return 0;
}
4. 멤버 사용
멤버 출력등 사용하는 방법은 어렵지 않다. 초기화 때 처럼 변수명.멤버명으로 출력할 수 있다.
#include <stdio.h>
typedef struct {
char name[20];
int age;
char major[20];
} INFO;
int main(void) {
INFO person = {"daehun", 25, "SW"};
printf("%s %d %s", person.name, person.age, person.major); // daehun 25 SW
return 0;
}
5. Call-by-reference
구조체를 변수를 Call-by-reference하여 사용해야할 경우가 있다. 당연하지만 아래 코드는 Call-by-value로 main 함수의 person 변수의 age 변수는 바뀌지 않는다.
#include <stdio.h>
typedef struct {
char name[20];
int age;
char major[20];
} INFO;
void changeInfo(INFO person) {
person.age = 10;
printf("changeInfo : %s %d %s\n", person.name, person.age, person.major);
// changeInfo : daehun 10 SW
}
int main(void) {
INFO person = {"daehun", 25, "SW"};
changeInfo(person);
printf("main : %s %d %s\n", person.name, person.age, person.major);
// main : daehun 25 SW
return 0;
}
아래 코드 처럼 Call-by-reference 기법을 활용하여 (*변수명).멤버명으로 값을 바꿀 수 있다.
#include <stdio
typedef struct {
char name[20];
int age;
char major[20];
} INFO;
void changeInfo(INFO *person) {
(*person).age = 10;
printf("changeInfo : %s %d %s\n", (*person).name, (*person).age, (*person).major);
// main : daehun 10 SW
}
int main(void) {
INFO person = {"daehun", 25, "SW"};
changeInfo(&person);
printf("main : %s %d %s\n", person.name, person.age, person.major);
// main : daehun 10 SW
return 0;
}
(*변수명).멤버명을 다르게 표현하여 변수명 → 멤버명으로도 값을 바꿀수 있다. 보통 → 를 많이 사용한다.
#include <stdio.
typedef struct {
char name[20];
int age;
char major[20];
} INFO;
void changeInfo(INFO *person) {
person->age = 10;
printf("changeInfo : %s %d %s\n", person->name, person->age, person->major);
}
int main(void) {
INFO person = {"daehun", 25, "SW"};
changeInfo(&person);
printf("main : %s %d %s\n", person.name, person.age, person.major);
return 0;
}
6. PE 구조
Window OS의 실행파일은 PE(Portable Executable) 구조를 가진다. PE 구조에는 실행파일의 실행코드와 실행코드를 실행하기위한 환경등이 기술되어있다. PE구조는 구조체로 멤버들을 관리하고 있는데, 헤더와 섹션의 하위 변수들은 모두 구조체로 구조체안에 구조체 등 복잡한 구조를 가지고 있습니다. 아래 사진 중 색깔로 하이라이트 된 부분은 모두 멤버입니다.
출처 : https://onlyf8.com/pe-format
참고할 만한 사이트
아래 사이트는 매우 유명한 reversecore 작가의 ‘리버싱 핵심원리’의 참고 사이트이다.
'초보 해커를 위한 C언어와 동작 원리 > Ch2. Programming' 카테고리의 다른 글
동적 할당 (0) | 2025.04.23 |
---|---|
문자열 함수 (0) | 2025.04.23 |
함수 (0) | 2025.04.23 |
배열과 포인터 (2) | 2025.04.22 |
포인터 (0) | 2025.04.22 |