이 페이지 요약
코딩도장 Unit 48 ~ 50
1. 구조체, 구조체에서 포인터 사용
2. 두 점 사이의 거리 구하기(math.h 헤더 파일의 함수들)
Unit 48. 구조체 사용하기
인적 정보를 처리할 경우 이름, 나이 , 주소 등을 저장할 변수가 필요하다. 각각 변수를 만들어 저장할 경우 한 사람의 정보만 저장할 수 있고, 여러명의 정보를 저장하려면 변수를 계속 만들어야 하므로 비효율 적이다.
구조체는 struct 키워드로 정의 하며 다음과 같이 사용할 수 있다.
struct Person {
char name[20]; // 이름
int age; // 나이
char address[100]; // 주소
};
이름, 나이, 주소 정보가 Person 이라는 구조체에 들어가 사람 단위로 정보를 처리할 수 있다.
구조체는 관련 정보를 하나의 의미로 묶을 때 사용한다. 목적에 맞는 자료형을 만들어서 사용하는데 기본 자료형을 조합하여 만든 자료형을 파생형이라 한다.
48.1 구조체를 만들고 사용하기
구조체는 struct 키워드로 정의한다. 정의 한 후 변수로 선언하여 사용한다.
다음은 인적 정보를 표현하는 구조체를 만들고 사용한 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <stdio.h>
#include <string.h>
struct Person {
char name[20];
int age;
int address[100];
};
int main()
{
struct Person p1;
strcpy(p1.name, "홍길동");
p1.age = 30;
strcpy(p1.address, "서울시 용산구");
printf("이름 : %s\n", p1.name);
printf("나이 : %d\n", p1.age);
printf("주소 : %s\n", p1.address);
return 0;
}
|
cs |
struct 키워드 뒤에 구조체 이름을 지정하고 중괄호 안에 변수를 선언한다. 구조체 안에 들어있는 변수를 멤버라고 부른다. 구조체를 정의할 때는 }(닫는 중괄호) 뒤에는 반드시 ; (세미클론)을 붙여줘야 한다. 구조체는 보통 main 함수 바깥에 정의한다. 함수 안에 구조체를 정의하면 해당 함수 안에서만 구조체를 사용할 수 있다.
정의한 구조체를 사용하려면 구조체 변수를 선언해야 하며 구조체 이름 앞에 struct 키워드를 붙여줘야 한다.
구조체 멤버에 접근할 때는 .(점)을 사용한다. p1.age = 30; 과 같이 구조체 멤버에 접근한 뒤 값을 할당하고 값을 가져온다. 문자열 멤버는 할당연산자로 저장할 수 없으므로 strcpy함수를 사용하면 된다.
다음과 같이 중괄호와 세미클론 사이에 변수를 지정하면 구조체를 정의하는 동시에 변수를 선언할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <stdio.h>
#include <string.h>
struct Person {
char name[20];
int age;
int address[100];
} p1;
int main()
{
strcpy(p1.name, "홍길동");
p1.age = 30;
strcpy(p1.address, "서울시 용산구");
printf("이름 : %s\n", p1.name);
printf("나이 : %d\n", p1.age);
printf("주소 : %s\n", p1.address);
return 0;
}
|
cs |
구조체를 정의하면서 닫는 중괄호와 세미클론 사이에 변수를 지정하면 구조체를 정의하는 동시에 변수가 선언된다. 이와 같이 선언된 변수 p1은 main함수 바깥에 선언되어 있으며 전역변수이다.
구조체 변수를 선언하는 동시에 값을 초기화 하려면 중괄호 안에 .(점)과 멤버 이름을 적고 값을 할당한다. 또한 멤버 이름과 할당 연산자 없이 값만 콤마로 구분하여 나열해도 되는데, 이러한 경우 처음부터 순서대로 값을 채워야 하며 중간에 있는 멤버만 값을 할당하거나 생략할 수 는 없다.
- struct 구조체이름 변수이름 = { .멤버이름1 = 값1, .멤버이름2 = 값2 };
- struct 구조체이름 변수이름 = {값1, 값2};
48.2 typedef로 struct 키워드 없이 구조체 선언하기
typedef로 구조체를 정의하며 별칭(alias)을 지정할 수 있다.
구조체 이름과 구조체 별칭은 겹쳐도 되지만 구분하기 위해 구조체 이름은 앞에 _을 붙이겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <stdio.h>
#include <string.h>
typedef struct Person_ {
char name[20];
int age;
int address[100];
} Person;
int main()
{
Person p1;
strcpy(p1.name, "홍길동");
p1.age = 30;
strcpy(p1.address, "서울시 용산구");
printf("이름 : %s\n", p1.name);
printf("나이 : %d\n", p1.age);
printf("주소 : %s\n", p1.address);
return 0;
}
|
cs |
구조체를 정의할 땐 맨 앞에 typedef를 붙이고, 구조체를 정의한다. 그리고 닫는 중괄호와 세미클론 사이에 구조체 별칭을 지정하면 된다.
구조체 변수를 선언할 때는 struct 키워드를 생략하고 구조체 별칭으로 바로 변수를 선언할 수 있다. 구조체 별칭으로 선언한 변수도 멤버에 접근할 때는 점을 사용한다.
struct 뒤에 붙는 구조체 이름은 원래 태그(tag)라 부른다.
48.3 익명 구조체 사용하기
typedef로 구조체를 정의하면서 이름을 생략할 수 있다. 변수는 구조체 별칭으로 선언하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <stdio.h>
#include <string.h>
typedef struct{
char name[20];
int age;
int address[100];
} Person;
int main()
{
Person p1;
strcpy(p1.name, "홍길동");
p1.age = 30;
strcpy(p1.address, "서울시 용산구");
printf("이름 : %s\n", p1.name);
printf("나이 : %d\n", p1.age);
printf("주소 : %s\n", p1.address);
return 0;
}
|
cs |
typedef struct 뒤에 이름을 지정하지 않고 바로 여는 중괄호로 시작하면 된다.
이때는 반드시 구조체 별칭을 지정해야 한다.
구조체 변수는 구조체 별칭으로 선언하고, 멤버에 접근할 때는 점으로 접근한다.
48.4 퀴즈
정답은 c이다.
정답은 c이다.
정답은 d 이다.
정답은 익명 구조체 이다.
48.5 연습문제 : 좌표 구조체 정의하기
정답은 다음 코드와 같다.
// 1.
Point2D{
int x;
int y;
};
// 2.
struct point2D
// 3.
p1.x = 10;
48.6 연습문제 : typedef로 좌표 구조체 정의하기
정답은 다음 코드와 같다.
// 1.
struct _Point2D{
int x;
int y;
} Point2D;
// 2.
p1
// 3.
p1.y = 20;
48.7 연습문제 : 익명 구조체로 좌표 구조체 정의하기
정답은 } Point2D; 이다.
48.8 심사문제 : 자동차 계기판 구조체 선언하기
정답은 다음코드와 같다.
struct Dashboard d1;
d1.speed = 80;
d1.fuel = 'F';
d1.mileage = 5821.442871f;
d1.engineTemp = 200;
d1.rpm = 1830;
48.9 심사문제 : 자동차 계기판 구조체 정의하기
정답은 다음 코드와 같다.
typedef struct _Dashboard{
int speed;
char fuel;
float mileage;
int engineTemp;
int rpm;
}Dashboard;
Unit 49. 구조체 포인터 사용하기
구조체는 멤버 변수가 여러 개 들어 있어 크기가 큰 편이기 때문에 구조체 변수를 일일이 선언해서 사용하는 것 보다 포인터에 메모리를 할당하여 사용하는 것이 효율적이다.
49.1 구조체 포인터를 선언하고 메모리 할당하기
다른 자료형 처럼 구조체도 포인터를 선언할 수 있으며 구조체 포인터에는 malloc함수를 사용하여 동적 메모리를 할당할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Person {
char name[20];
int age;
char address[100];
};
int main()
{
struct Person *p1 = malloc(sizeof(struct Person));
strcpy(p1->name, "홍길동");
p1->age = 30;
strcpy(p1->address, "서울시 용산구");
printf("이름 : %s\n", p1->name);
printf("나이 : %d\n", p1->age);
printf("주소 : %s\n", p1->address);
free(p1);
return 0;
}
|
cs |
struct 키워드와 구조체 이름을 사용하여 구조체 포인터를 선언한다. 포인터 변수 이므로 반드시 *을 붙인다. malloc함수로 메모리를 할당 할 때 sizeof(struct Person)과 같이 구조체 크기를 구하여 넣어준다.
구조체의 멤버에 접근할 때는 점이 아닌 -> (화살표 연산자)를 사용한다.
p1->name 같은 문자열 멤버는 할당연산자로 저장할 수 없기 때문에 strcpy 함수를 사용하면 된다.
사용이 끝났으면 free 함수를 사용하여 할당한 메모리를 해제한다.
(*p1).age 처럼 역참조를 사용하면 점으로 멤버에 접근할 수 있다.
49.2 구조체 별칭으로 포인터를 선언하고 메모리 할당하기
구조체별칭 *포인터이름 = malloc(sizeof(구조체별칭)); 의 형태로 포인터를 선언하고 메모리를 할당할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct _Person {
char name[20];
int age;
char address[100];
} Person;
int main()
{
Person *p1 = malloc(sizeof(Person));
strcpy(p1->name, "홍길동");
p1->age = 30;
strcpy(p1->address, "서울시 용산구");
printf("이름 : %s\n", p1->name);
printf("나이 : %d\n", p1->age);
printf("주소 : %s\n", p1->address);
free(p1);
return 0;
}
|
cs |
구조체 별칭을 사용하여 포인터를 바로 선언한 뒤 malloc 함수로 메모리를 할당하면 된다. 할당하는 메모리 크기도 구조체 별칭으로 바로 구할 수 있다. 구조페를 다 사용했으면 free 함수로 메모리를 해제해주면 된다.
익명 구조체도 사용하려면 구조체 별칭을 지정해줘야 하므로 메모리 할당 방법은 위와 동일하다.
49.3 구조체 포인터에 구조체 변수의 주소 할당하기
동적 메모리를 할당하지 않고 구조체 변수에 &(주소 연산자)를 사용하여 구조체 포인터를 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Person {
char name[20];
int age;
char address[100];
};
int main()
{
struct Person p1;
struct Person *ptr;
ptr = &p1;
ptr->age = 30;
printf("나이 : %d\n", p1.age);
printf("나이 : %d\n", ptr->age);
return 0;
}
|
cs |
먼저 구조체 변수를 선언하고, 구조체 포인터를 선언한다.
구조체 변수는 주소 연산자 &를 사용하여 메모리 주소를 구할 수 있으며 메모리 주소는 구조체 포인터에 할당할 수 있다.
ptr은 구조체 포인터이므로 -> 으로 멤버에 접근하여 값을 할당하였다.
ptr은 p1의 메모리 주소 이므로 ptr의 멤버를 수정하면 결국 p1의 멤버도 바뀐다.
49.4 퀴즈
정답은 4 이다.
정답은 d 이다.
정답은 d 이다.
49.5 연습문제 : 학생 구조체 포인터에 메모리 할당하기
정답은 다음코드와 같다.
// 1.
malloc(sizeof(struct Student))
// 2.
strcpy(s1->name, "고길동")
s1->grade = 1;
s1->class = 3;
s1->average = 65.389999f;
49.6 연습문제 : 3차원 좌표 구조체 포인터에 메모리 할당하기
정답은 다음 코드와 같다.
// 1.
malloc(sizeof(Point3D));
// 2.
p1->x = 10.0f;
p1->y = 20.0f;
p1->z = 30.0f;
49.7 연습문제 : 구조체 포인터에 구조체 주소 할당하기
정답은 다음 코드와 같다.
// 1.
struct Item *ptr;
// 2.
ptr = &item1;
49.8 심사문제 : 사람과 자동차 구조체 포인터에 메모리 할당하기
정답은 다음 코드와 같다.
struct Person *p1 = malloc(sizeof(struct Person));
Car *c1 = malloc(sizeof(Car));
strcpy(p1->name, "고길동");
p1->age = 40;
strcpy(p1->address, "서울시 서초구 반포동");
strcpy(c1->name, "스텔라");
c1->number = 3421;
c1->displacement = 2000;
49.9 심사문제 : 구조체 포인터에 구조체 변수의 주소 할당하기
정답은 다음 코드와 같다.
ptr = &p1;
Unit 50. 두 점 사이의 거이 구하기
50.1 두 점 사이의 거리 구하기
2차원 평면에서 위치를 표현하려면 x와 y값이 필요하다. 구조체를 이용하여 한 점에 x와 y값을 선언하여 점을 표현할 수 있다.
두 점 사이의 거리를 구하려면 피카고라스의 정리를 이용하면 된다.
점 두 개가 있을 때 직각 삼각형을 그리면 다음과 같다.
피타고라스의 정리를 이용하여면 먼저 선 a 와 b의 길이를 구해야 하는데 구조체 변수에 두 점의 좌표가 들어있다고 가정하면 다음과 같이 구할 수 있다.
int a = p2.x - p1.x; // 선 a의 길이
int b = p2.y - p1.y; // 선 b의 길이
피타고라스 정리에서 c의 길이를 구하려면 제곱근을 구해야 한다.
C에서 루트는 math.h 헤더파일에 선언된 sqrt 함수를 사용하여 구할 수 있다.
C 코드로 두 점의 거리를 구하는 방법은 다음같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#include <stdio.h>
#include <math.h>
struct Point2D {
int x;
int y;
};
int main()
{
struct Point2D p1;
struct Point2D p2;
p1.x = 30;
p1.y = 20;
p2.x = 60;
p2.y = 50;
int a = p2.x - p1.x;
int b = p2.y - p1.y;
double c = sqrt((a*a) + (b*b));
printf("%f\n", c);
return 0;
}
|
cs |
sqrt 함수를 사용하면 넣은 값의 제곱근을 구할 수 있다. 제곱근은 소수로 나오기 때문에 double형 변수에 저장했다.
제곱을 구할 때는 math.h 헤더파일에 선언되있는 pow 함수를 사용해도 된다. a^2를 구하고 싶으면 pow(a,2)와 같이 사용한다.
abs, fabs, fabsf 함수를 사용하면 각각 정수, double형 실수, float형 실수에 대한 절댓값을 구할 수 있다.
50.2 연습문제 : 사각형의 넓이 구하기
정답은 다음 코드와 같다.
int w = abs(rect.x2 - rect.x1);
int h = abs(rect.y2 - rect.y1);
area = w * h;
밑변과 높이를 구하면서 음수가 나올수 있기 때문에 절댓값을 구하는 abs 함수를 사용하였다.
50.3 심사문제 : 두 점 사이의 거리 구하기
정답은 다음 코드와 같다.
int a = p2.x - p1.x;
int b = p2.y - p1.y;
distance = sqrt((a*a) + (b*b));
'Project H4C Study Group' 카테고리의 다른 글
[Project H4C][Hack CTF] Basic_BOF #2 (0) | 2021.03.16 |
---|---|
[Project H4C][Hack CTF] Basic_BOF #1 (0) | 2021.03.16 |
[Project H4C] C언어 코딩도장(11) (0) | 2021.03.11 |
[Project H4C] C언어 코딩도장(10) (0) | 2021.03.10 |
[Project H4C] C언어 코딩도장(9) (0) | 2021.03.10 |