Guest User

Untitled

a guest
Dec 15th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.65 KB | None | 0 0
  1. # C에서의 구조체
  2.  
  3. ## 들어가면서
  4.  
  5. 코딩 꼭 같이 해보면서 해보세요.. ㅠㅠ 그럼 더 이해 잘 될것 같네요..
  6.  
  7. ## 1. 배경
  8.  
  9. 만약 학생을 데이터로 표현하고 싶다고하면, 이름, 학번, 학년을 데이터로 저장해야 한다.
  10.  
  11. 이때 `char name[] = "홍길동";` `int id = 1871000;` `int grade = 1;` 이런식으로 3개씩 선언하여 사용해야한다.
  12.  
  13. 하지만 학생을 100명 표현해야한다면?? --> 많이 힘들다... ㅠㅠ
  14.  
  15. 그래서! 구조체가 나왔당
  16.  
  17. ```c
  18. struct student {//구조체의 이름이 student인 구조체 선언
  19. char name[30];//char[30] 이름 배열
  20. int id;//학번
  21. int grade;//학년
  22. };
  23. ```
  24.  
  25. 로 구조체를 만들 수 있다.
  26.  
  27. main에서 사용할때는 `struct student person;` 으로 선언할 수 있다.
  28.  
  29. > 여기서 `struct student` 가 자료형이고, `person`이 변수명이예요 주의.
  30.  
  31.  
  32.  
  33. ## 2. 사용법
  34.  
  35. 구조체를 정의하고 만들었다면, 사용도 해야겠죠!
  36.  
  37. ```c
  38. #include <stdio.h>
  39.  
  40. struct student {//구조체의 이름이 student인 구조체 선언
  41. char name[30];//char[30] 이름 배열
  42. int id;//학번
  43. int grade;//학년
  44. };
  45.  
  46. int main(void) {
  47. struct student person = { "홍길동", 1871000, 1 };
  48. printf("%s\n", person.name);
  49. printf("%d\n", person.id);
  50. printf("%d\n", person.grade);
  51.  
  52. scanf("%s", person.name);
  53. scanf("%d", &person.id);
  54. scanf("%d", &person.grade);
  55.  
  56. return 0;
  57. }
  58. ```
  59.  
  60. main함수에서 구조체를 선언한 후에, 값을 바로 할당하는 것을 해봤습니다. 선언하고 바로 할당하고 싶다면 중괄호로 구조체안의 내용물을 채워준다고 생각하면 될 거 같아요.
  61.  
  62. 그래서 "홍길동"은 name에, 1871000은 id에, 1은 grade에 각각 맵핑됩니다. 그리고 11~13까지는 출력하는 부분입니다. 구조체변수에 접근하고 싶다면 `구조체변수의이름.변수명` 으로 접근할 수 있어요. 여기서는 person이 구조체의 변수명이니까, `person.name`, `person.id`, `person.grade` 로 접근하는 것이죠.
  63.  
  64. 그리고 입력을 하고싶다! 하면 똑같이 scanf를 사용해서 구조체의 어디에 입력할 것인지 정하면됩니다. `scanf("%s", person);` 이런건 절대 안됩니다! 구조체에 직접 입력을 할 순 없습니다. 구조체의 __어떤변수__에 입력할 것인지 확실하게 정해주어야 합니다.
  65.  
  66. > 여기서 `scanf("%s", person.name);` 은 왜 &가 없냐? -> 배열의 이름은? 배열의 시작주소! 가 여기서도 적용됩니다. 따라서 %s로 문자열을 입력받을 때, person.name은 구조체 안에있는 name배열의 시작주소이지요? 그래서 &가 안붙습니다. 다른변수들은 일반 변수사용시와 같이 &를 꼭! 붙여주어야 합니다.
  67.  
  68.  
  69.  
  70. ## 3. 구조체 배열
  71.  
  72. 저희가 `int arr[10];` 이렇게 자료형에 대한 배열을 만들었었죠. 구조체또한 가능합니다. 구조체도 엄연히 사용자 정의__자료형__ 이기 때문이죠.
  73.  
  74. `struct student person[10];` 으로 선언할 수 있습니다. 여기서부터는 제가 구조체좀 쉽게 쓰려고 합니다.
  75.  
  76. ```c
  77. typedef struct student {
  78. char name[30];
  79. int id;
  80. int grade;
  81. }Student;
  82. ```
  83.  
  84. 이렇게 하게되면 struct person 을 Person으로 맵핑해서 사용하겠다는 겁니다. 즉, typedef A B는 A를 B로 사용하겠다는 것이죠. 사용 할때에는 `Person a;` 로하면 `struct person a;` 와 같은 효과입니다.
  85.  
  86. > typedef int data;
  87. >
  88. > data i = 10; 이렇게 하게되면 data는 int 인 것입니다. 따라서 위의 typedef 문은 Person을 사용할 때 struct person을 사용하겠다는 것입니다.
  89.  
  90.  
  91.  
  92. typedef 를 적용하면,
  93.  
  94. `Student person[10];` 이렇게 __구조체배열__ 을 선언할 수 있죠. 전에 저희가 int 형 배열을 선언해서 [0], [1] 이렇게 접근한 것 처럼 구조체배열도 똑같이 접근할 수 있습니다. arr[0] 이렇게하면 구조체배열의 첫번째 값에 접근한겁니다. 그렇다면 `person[0].name` 은 첫 번째 구조체의 name 변수가 되는거죠. 마찬가지로 `person[0].id, person[0].grade` 에 값을 쓰거나 읽을 수 있습니다. 배열이나오면 항상따라오는것이 반복문이죠 ㅎㅎ
  95.  
  96. ```c
  97. #include <stdio.h>
  98.  
  99. typedef struct student {
  100. char name[30];
  101. int id;
  102. int grade;
  103. }Student;
  104.  
  105. int main(void) {
  106. Student arr[10];//구조체 배열 선언
  107. for (int i = 0; i < 10; i++) {//데이터 입력부분
  108. scanf("%s %d %d", arr[i].name, &arr[i].id, &arr[i].grade);
  109. }
  110.  
  111. for (int i = 0; i < 10; i++) {//데이터 출력부분
  112. printf("%s %d %d", arr[i].name, arr[i].id, arr[i].grade);
  113. }
  114.  
  115. return 0;
  116. }
  117. ```
  118.  
  119. 이처럼 구조체배열을 잘 이용하실 수 있어야합니다..
  120.  
  121.  
  122.  
  123. ## 4. 구조체 포인터
  124.  
  125. 전에 했던 코드를 살펴볼까여
  126.  
  127. ```c
  128. int a = 10;
  129. int* p = &a;
  130. ```
  131.  
  132. 이렇게 하면 p를 이용해서 a값을 변경하거나 출력할 수 있죠.
  133.  
  134. >(*p)로 a의 값을 바꾸거나 얻을 수 있죠.
  135.  
  136. ---
  137.  
  138. 구조체의 포인터도 마찬가지입니다!
  139.  
  140. ```c
  141. typedef struct student {
  142. char name[30];
  143. int id;
  144. int grade;
  145. }Student;
  146.  
  147. Student person = { "홍길동", 1871000, 1 };
  148. Student* p = &person;
  149. ```
  150.  
  151. 같은 방식입니다. Student 구조체 자료형인 person을 선언하고 값을 할당한 후에, Student 구조체자료형의 _포인터_ 인 p를 선언하고 p는 person을 가리킵니다. 여기까진 같습니다.
  152.  
  153. 하지만 멤버 접근시에 달라지는데요, 위에서 값에 접근할 때 \*을 사용한다고 했습니다. 그렇다면 구조체에서 똑같이 적용할 수 있습니다. `(*p).name` , `(*p).id` , `(*p).grade` 로 접근하실 수 있습니다. 여기서 (*person) 을 괄호로 감싸준 이유는 . 연산자가 * 연산자보다 더 우선순위가 높기 때문입니다. 그래서 불편하죠?... ㅠㅠ 맨날 감싸줘야 되서요..
  154.  
  155. 그래서 ->가 나왔습니다! 구조체 포인터한정으로 구조체 포인터가 있을 때 -> 연산자를 이용해서 구조체의 멤버에 접근할 수 있도록 했습니다.
  156.  
  157. ```c
  158. #include <stdio.h>
  159.  
  160. typedef struct student {
  161. char name[30];
  162. int id;
  163. int grade;
  164. }Student;
  165. int main(void) {
  166. Student person;
  167. Student* p = &person;
  168.  
  169. scanf("%s", p->name);
  170. //scanf("%d", (*p).name);와 동일(왜 &안붙는지는 아시죠?)
  171. scanf("%d", &p->id);
  172. //scanf("%d", &(*p).id);와 동일
  173. scanf("%d", &p->grade);
  174. //scanf("%d", &(*p).grade);와 동일
  175.  
  176.  
  177. printf("%s\n", p->name);//(*p).name
  178. printf("%d\n", p->id);//(*p).id
  179. printf("%d\n", p ->grade);//(*p).grade;
  180.  
  181. return 0;
  182. }
  183.  
  184. ```
  185.  
  186. 이런식으로 말이죠.. 괄호로 감싸주고.. 별찍고 변수명 할 필요없이 ->면 바로 접근할 수 있어서 좋은겁니다!
Add Comment
Please, Sign In to add comment