C언어/참고서: C언어 콘서트

[C언어 53차시] 구조체 변수의 대입, 비교, 구조체 배열, 구조체와 함수, 구조체와 포인터, 간접 멤버 연산자, indirect membership operator, ->

Olivia-BlackCherry 2023. 4. 14. 12:29

1. 구조체 변수 대입 가능

// 구조체 정의
struct point {
	int x;
	int y;
};

int main() {
	struct point p = { 1, 2 };
	struct point q = p;

	printf("%d %d\n", p.x, p.y);
	printf("%d %d\n", q.x, q.y);

	return 0;
}

>>1,2 

1,2

 

// 구조체 정의
struct point {
	int x;
	int y;
};

int main() {
	struct point p = { 1, 2 };
	struct point q = p;

	p.x = q.y;
	p.y = q.x;
	printf("%d %d\n", p.x, p.y);
	printf("%d %d\n", q.x, q.y);

	return 0;
}

>>2, 1

1, 2

 

 

2. 구조체 변수 비교

구조체 변수와 구조체 변수를 바로 비교하는 것은 XXXXXX

p==q 

불가능하다. 

 

대신, 멤버마다 별도의 비교 수식을 주면 가능하다. 

p.x == q.x 

p.y == q.y

가능하다.

 

 

3. 구조체 배열

배열 원소가 구조체이다. 

즉, 구조체가 여러 개 모인 것이다.

 

 

3-1 구조체 배열 선언

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

// 구조체 정의
struct student {
	int number;
	char name[10];
	double tall;
};

int main() {
	struct student university[10];
	university[0].number = 1;
	strcpy(university[0].name, "Jenny");
	university[0].tall = 1.8;

	university[1].number = 2;
	strcpy(university[1].name, "Olivia");
	university[1].tall = 1.6;

	university[2].number = 3;
	strcpy(university[2].name, "Tony");
	university[2].tall = 1.7;

	printf("%d %s %lf", university[0].number, university[0].name, university[0].tall);
	return 0;
}

>>1 Jenny 1.800000

 

 

3-2 구조체 배열 초기화

{ } 안에 { }를 넣는다. 

	struct student highschool[10] = {
		{1, "jenny", 1.85},
		{2, "olivia", 1.65},
		{3, "tony", 1.75}
	};

 

 

4. 연습문제- 객관식 퀴즈 만들기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define SIZE 100 

// 구조체 정의
struct QUESTION {
	char question[SIZE];
	char item1[SIZE];
	char item2[SIZE];
	char item3[SIZE];
	int solution;
};

struct QUESTION favorite[3] = {
	{"가장 선호하는 해외여행은?", "미술관", "뮤지컬", "축구경기",1},
	{"가장 선호하는 취미활동은?", "운동", "책읽기", "여행",1},
	{"가장 선호하는 음식은?", "한식", "중식", "일식",1}
};

int main() {
	int select;
	for (int i = 0; i <3; i++) {
		printf("%s\n", favorite[i].question);
		printf("%s %s %s\n", favorite[i].item1, favorite[i].item2, favorite[i].item3);
		scanf("%d", &select);
		if (select == favorite[i].solution) printf("맞았습니다\n\n");
		else printf("틀렸습니다.\n\n");
	}
	return 0;
}

 

 

5. 구조체와 함수

1) 함수의 인수

함수의 인수로 구조체를 쓸 수 있다. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int equal(struct teacher t1, struct teacher t2);

struct teacher {
	char name[10];
	int number;
};

int main(void)
{
	int result;
	struct teacher t1 = { "olivia", 10 };
	struct teacher t2 = { "tony", 20 };
	result =equal(t1, t2);
	if (result == 1) printf("이름이 같습니다");
	else printf("다른 이름입니다");
}

int equal(struct teacher t1, struct teacher t2)
{
	if (strcmp(t1.name, t2.name) == 0) return 1;
	else return 0;
}

 

2) 함수의 반환값

반환값의 형을 구조체로 표시한다. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct teacher make_teacher();

struct teacher {
	char name[10];
	int number;
};

int main(void)
{
	struct teacher result;
	
	result = make_teacher();
	printf("%s %d", result.name, result.number);
}

struct teacher make_teacher(void)
{
	struct teacher t;
	scanf("%s %d", &t.name, &t.number);
	return t;
}

 

 

6. 연습문제- 두 벡터의 합 구하는 함수 제작하기

두 벡터의 합 구하는 방법

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct vector get_vector_sum(struct vector a, struct vector b);

//구조체 선언(태그, 멤버)
struct vector
{
	int x;
	int y;
};

int main(void)
{
	struct vector result;
	struct vector point[2] =
	{
		{5,1},
		{6,4}
	};
	result = get_vector_sum(point[0], point[1]);
	printf("%d, %d", result.x, result.y);
}

struct vector get_vector_sum(struct vector a, struct vector b)
{
	struct vector sum;
	sum.x = a.x + b.x;
	sum.y = a.y + b.y;
	return sum;
}

>>11, 5

 

 

7. 구조체와 포인터, ->

구조체를 가리키는 포인터를 만들어보자.

1) 구조체 선언

vector 태그의 구조체를 선언했다. 멤버는 x, y이며 point 변수로 초기화했다.

struct vector
{       int x;
        int y;
};
struct vector point = {5, 1};

 

2) 포인터 선언

vector 구조체를 가리키는 포인터 p를 선언했다.

struct vector *p;

 

3) 구조체 변수 주소 추출

구조체의 변수의 주소를 추출한다.

&point

 

4) 포인터에 구조체 변수 주소 대입

포인터 p에 구조체 변수의 주소를 대입한다.

p=&point

 

5) 값 출력

값을 출력한다. 

여기서 주의할 점은 포인터를 이용해서 구조체 멤버 x에 접근하려면 괄호를 다음과 같이 한다. (*p).x

 *p.x를 하면 p.x가 먼저 계산되기 때문이다. 

printf("%d, %d", (*p).x, (*p).y);

>>5, 1

 

6) 간접 멤버 연산자  -> 

포인터로 구조체 멤버를 가리킬 때 -> 연산자를 사용한다. 

indirect membership operator이라고 불린다. 

구조체 포인터를 이용하여 멤버에 접근할 때 쓴다. 

(*p).x 
p->x
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct vector get_vector_sum(struct vector a, struct vector b);

//구조체 선언(태그, 멤버)
struct vector
{
	int x;
	int y;
};

int main(void)
{
	struct vector point = { 5, 1 };
	struct vector* p;
	p = &point;

	printf("%d, %d\n", point.x, point.y);
	printf("%d, %d\n", (*p).x, (*p).y);
	printf("%d, %d", p->x, p->y);
}

>>5,1

5,1

5,1

 

 

8. 연습문제

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
struct employee {
	char name[30];
	int salary;
};


int main(void) {
	struct employee people[10];
	strcpy(people[0].name, "olivia");
	people[0].salary = 1000;
	
	strcpy(people[1].name, "Tony");
	people[1].salary = 1000;

	strcpy(people[2].name, "Sumi");
	people[2].salary = 4000;

	scanf("%s", &people[3].name);
	scanf("%d", &people[3].salary);

	printf("%s %d\n", people[0].name, people[0].salary);
	printf("%s %d\n", people[1].name, people[1].salary);
	printf("%s %d\n", people[2].name, people[2].salary);
	printf("%s %d\n", people[3].name, people[3].salary);
}

>>olivia 1000
Tony 1000
Sumi 4000
jenny 1000