|
| 1 | +--- |
| 2 | +sidebar_position: 9 |
| 3 | +title: 구조체와 예제 |
| 4 | +description: 구조체 문법을 이해하고, 구조체의 다양한 활용법을 습득 |
| 5 | +--- |
| 6 | + |
| 7 | +## 1. 주요 개념 및 내용 |
| 8 | + |
| 9 | +### 1.1. 구조체의 개요 |
| 10 | + |
| 11 | +#### 1) 개념 |
| 12 | + |
| 13 | +- **배열:** |
| 14 | + 동일한 데이터 타입을 갖는 자료들을 동일한 이름으로 묶어 놓은 것 |
| 15 | + 예: `int a[10];` (모두 정수형 데이터) |
| 16 | + |
| 17 | +- **구조체:** |
| 18 | + 서로 다른 데이터 타입을 갖는 자료들을 동일한 이름으로 묶어 놓은 것 |
| 19 | + 예: |
| 20 | + ```c |
| 21 | + struct a { |
| 22 | + int num; |
| 23 | + char name[20]; |
| 24 | + }; |
| 25 | + ``` |
| 26 | + (정수와 문자열을 하나의 이름으로 묶음) |
| 27 | +
|
| 28 | +--- |
| 29 | +
|
| 30 | +#### 2) 구조체 선언 |
| 31 | +
|
| 32 | +- `struct` 키워드를 사용하여 구조체를 정의 |
| 33 | +- 형식: |
| 34 | + ```c |
| 35 | + struct 구조체이름 { |
| 36 | + 멤버1; |
| 37 | + 멤버2; |
| 38 | + ... |
| 39 | + }; |
| 40 | + ``` |
| 41 | + - 각 멤버 선언 후 세미콜론(`;`) 필요 |
| 42 | + - 구조체 선언 마지막에도 세미콜론(`;`) 필수 |
| 43 | +- 일반적으로 `main()` 함수 전에 선언 |
| 44 | +- 예시: |
| 45 | + ```c |
| 46 | + struct customer { |
| 47 | + int num; |
| 48 | + char name[20]; |
| 49 | + double point; |
| 50 | + }; |
| 51 | + ``` |
| 52 | +
|
| 53 | +--- |
| 54 | +
|
| 55 | +#### 3) 구조체 변수 선언 |
| 56 | +
|
| 57 | +- 선언된 구조체 형식을 사용하여 변수를 생성 |
| 58 | +- 형식: |
| 59 | + ```c |
| 60 | + struct 구조체이름 변수명; |
| 61 | + ``` |
| 62 | +- 초기화 형식: |
| 63 | + ```c |
| 64 | + struct customer a1 = {1, "kim hy", 109.99}; |
| 65 | + ``` |
| 66 | +
|
| 67 | +--- |
| 68 | +
|
| 69 | +#### 4) 구조체 멤버 접근 |
| 70 | +
|
| 71 | +- 구조체 변수의 멤버에 접근할 때는 온점(`.`) 연산자 사용 |
| 72 | +- 형식: |
| 73 | + ```c |
| 74 | + 구조체변수.멤버명 |
| 75 | + ``` |
| 76 | +- 예시: |
| 77 | + ```c |
| 78 | + printf("num=%d name=%s point=%lf\n", a1.num, a1.name, a1.point); |
| 79 | + ``` |
| 80 | +
|
| 81 | +--- |
| 82 | +
|
| 83 | +#### 5) 구조체 배열 |
| 84 | +
|
| 85 | +- 여러 개의 구조체 인스턴스를 묶어 놓은 배열 |
| 86 | +- 형식: |
| 87 | + ```c |
| 88 | + struct 구조체이름 배열이름[크기]; |
| 89 | + ``` |
| 90 | +- 초기화 형식: |
| 91 | + ```c |
| 92 | + struct student a[3] = { {100,90,80}, {90,90,80}, {100,100,100} }; |
| 93 | + ``` |
| 94 | +- 배열 멤버 접근: |
| 95 | + ```c |
| 96 | + a[0].num, a[1].kor |
| 97 | + ``` |
| 98 | + |
| 99 | +--- |
| 100 | + |
| 101 | +### 1.2. typedef의 문법 이해 |
| 102 | + |
| 103 | +- `typedef`는 **새로운 이름으로 명명**하는 데 사용되는 키워드 |
| 104 | +- 복잡하거나 긴 데이터 타입 이름에 간결한 별칭 부여 |
| 105 | +- 구조체와 함께 사용 예시: |
| 106 | + ```c |
| 107 | + typedef struct student { |
| 108 | + int num; |
| 109 | + float kor; |
| 110 | + } St; |
| 111 | + ``` |
| 112 | + 또는 |
| 113 | + ```c |
| 114 | + typedef struct { |
| 115 | + int num; |
| 116 | + float kor; |
| 117 | + } St; |
| 118 | + ``` |
| 119 | +- 사용 예: |
| 120 | + ```c |
| 121 | + St st; |
| 122 | + ``` |
| 123 | +- 다른 자료형에도 사용 가능: |
| 124 | + ```c |
| 125 | + typedef unsigned int ui; |
| 126 | + ``` |
| 127 | + |
| 128 | +--- |
| 129 | + |
| 130 | +### 1.3. 구조체의 다양한 활용 |
| 131 | + |
| 132 | +#### 1) 구조체와 포인터 변수 |
| 133 | + |
| 134 | +- 구조체의 주소를 저장하는 포인터 변수 선언 가능 |
| 135 | +- 선언 형식: |
| 136 | + ```c |
| 137 | + struct 구조체이름 *포인터변수이름; |
| 138 | + ``` |
| 139 | +- 주소 할당 예시: |
| 140 | + ```c |
| 141 | + struct a *pTest; |
| 142 | + struct a p = {1, 100.99}; |
| 143 | + pTest = &p; |
| 144 | + ``` |
| 145 | +
|
| 146 | +--- |
| 147 | +
|
| 148 | +#### 2) 구조체 포인터와 `->` 연산자 |
| 149 | +
|
| 150 | +- 구조체 포인터를 통해 구조체 멤버의 값에 접근할 때 사용 |
| 151 | +- 두 가지 방법 |
| 152 | + - 간접 참조 연산자 `*`와 온점 `.` 사용: |
| 153 | + ```c |
| 154 | + (*pTest).num |
| 155 | + ``` |
| 156 | + - `->` 연산자 사용 (더 일반적이고 간결): |
| 157 | + ```c |
| 158 | + pTest->num |
| 159 | + ``` |
| 160 | +- 예시: |
| 161 | + ```c |
| 162 | + printf("num=%d total=%lf\n", pTest->num, pTest->total); |
| 163 | + ``` |
| 164 | + |
| 165 | +--- |
| 166 | + |
| 167 | +#### 3) 구조체와 함수 |
| 168 | + |
| 169 | +- 함수 호출 시 구조체 변수를 인자로 전달 가능 |
| 170 | + ```c |
| 171 | + sum(t1); |
| 172 | + ``` |
| 173 | +- 함수 정의/사용 시 구조체 변수를 매개변수로 받을 수 있음 |
| 174 | + ```c |
| 175 | + void sum(struct student a) { ... } |
| 176 | + ``` |
| 177 | +- 구조체 변수는 하나의 자료형으로 취급되어 함수 인자로 전달 시 하나의 단위로 처리 |
| 178 | +- 함수 내에서는 전달받은 구조체 형태의 지역 변수를 통해 멤버 직접 활용 가능 |
| 179 | + |
| 180 | +--- |
| 181 | + |
| 182 | +## 2. Visual Studio scanf 에러 해결 (`_CRT_SECURE_NO_WARNINGS`) |
| 183 | + |
| 184 | +- **에러 발생 이유:** |
| 185 | + 시스템 안정성과 보안을 확보하기 위함으로, `scanf` 함수가 안전하지 않을 수 있다는 경고 발생 |
| 186 | +- **에러 메시지 예시:** |
| 187 | + ``` |
| 188 | + error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. |
| 189 | + ``` |
| 190 | +- **해결 방법:** |
| 191 | + 1. `scanf_s` 함수 사용 (권장) |
| 192 | + 2. `#define _CRT_SECURE_NO_WARNINGS`를 코드 상단에 추가 |
| 193 | + 3. Visual Studio 프로젝트 설정 변경: |
| 194 | + "프로젝트 > 속성 > 구성속성 > C/C++ > 전처리기"에서 ; 뒤에 `_CRT_SECURE_NO_WARNINGS` 추가 |
| 195 | + 4. `#pragma warning(disable : 4996)`를 코드 상단에 추가 |
| 196 | + |
| 197 | +--- |
| 198 | + |
| 199 | +## 3. 학습 정리 (요약) |
| 200 | + |
| 201 | +- **배열:** 동일한 데이터 타입 묶음 |
| 202 | + 예: `int a[10];` |
| 203 | +- **구조체:** 서로 다른 데이터 타입 묶음 |
| 204 | + 예: |
| 205 | + ```c |
| 206 | + struct a { int num; char name[20]; }; |
| 207 | + ``` |
| 208 | +- **구조체 선언:** `struct` 키워드, 멤버 나열, 마지막 세미콜론 필수 |
| 209 | +- **구조체 변수 선언:** |
| 210 | + ```c |
| 211 | + struct 구조체이름 변수명; |
| 212 | + ``` |
| 213 | + 초기화: `{값, 값, ...}` |
| 214 | +- **구조체 멤버 접근:** |
| 215 | + ```c |
| 216 | + 구조체변수.멤버명 |
| 217 | + ``` |
| 218 | +- **구조체 배열:** |
| 219 | + ```c |
| 220 | + struct 구조체이름 배열이름[크기]; |
| 221 | + ``` |
| 222 | + 초기화: `{ {,,},{..},... }` |
| 223 | +- **구조체와 포인터:** |
| 224 | + 구조체의 주소를 저장하는 포인터 선언 가능 |
| 225 | + ```c |
| 226 | + struct 구조체이름 *포인터변수; |
| 227 | + ``` |
| 228 | +- **포인터 멤버 접근:** |
| 229 | + - `(*포인터변수).멤버` |
| 230 | + - `포인터변수->멤버` (권장) |
| 231 | +- **구조체와 함수:** |
| 232 | + 구조체 변수를 함수 인자로 전달하거나 반환할 수 있음 |
| 233 | + ```c |
| 234 | + void test(struct a aa, struct a bb) |
| 235 | + ``` |
0 commit comments