본문 바로가기
코스웨어/16년 스마트컨트롤러

2016-08-24_조재찬_스터디일지_C언어-구조체

by 알 수 없는 사용자 2016. 8. 25.
728x90
반응형
/*
중첩된 구조체의 정의
Point 구조체(x, y pos), Circle 구조체(Point cen, double rad)
center, radius를 보여주는 함수를 정의하고 메인함수에서 출력
*/

#include <stdio.h>
typedef struct
{
	int xpos;
	int ypos;
}Point;
typedef struct
{
	Point cen;
	double rad;
}Circle;
Circle GetCircleInfo(void)
{
	Circle cir;
	printf("원의 중심 입력: ");
	scanf("%d %d", &cir.cen.xpos, &cir.cen.ypos);
	printf("반지름 입력: ");
	scanf("%f", &cir.rad);
	return cir;
}
void ShowPosition(Circle pos)
{
	printf("[%d %d] \n %g", pos.cen.xpos, pos.cen.ypos, pos.rad);
}
int main()
{
	Circle Cir = GetCircleInfo();
	ShowPosition(Cir);

	return 0;
}

/* 문자열 형태의 '종업원 이름'과 '주민번호', 정수형태의 '급여정보'를 저장할
 employee 구조체 정의하고 변수 하나 선언

 프로그램 사용자에게 입력받고 구조체의 데이터 출력
 */
#include <stdio.h>

struct employee
{
	char name[20];
	char num[20];
	int pay;
};

int main()
{
	struct employee arr[3];
	int i;

	for (i = 0; i < 3; i++)
	{
		printf("종업원%d 이름 : ", i + 1);
		scanf("%s", &arr[i].name);
		printf("종업원%d 주민번호 : ", i + 1);
		scanf("%s", &arr[i].num);
		printf("종업원%d 월급 : ", i + 1);
		scanf("%d", &arr[i].pay);
	}

	for (i = 0; i < 3; i++)
		printf("[이름 : %s 주민번호 : %s 월급 : %d] ", arr[i].name, arr[i].num, arr[i].pay);

	return 0;
}

/*
point(x-y pos) 구조체와 circle 구조체를 정의하고
circle구조체(radius, center)의 center멤버는 포인터 변수를 활용해 point 구조체 멤버를 가리키도록 하라.
그리고 두 구조체의 내용(반지름과 원의 중심)을 출력
*/
#include <stdio.h>
struct point
{
	int xpos;
	int ypos;
};
struct circle
{
	double radius;
	struct point * center;
};
int main()
{
	struct point centerXY = { 1,3 };
	double rad = 4.4;

	struct circle ring = { rad, &centerXY };
	printf("원 반지름 : %g \n", ring.radius);
	printf("원의 중심 : %d %d \n", ring.center->xpos, ring.center->ypos);

	return 0;
}


Output:
1
2
원 반지름 : 4.4 
원의 중심 : 1 3 



/*
함수로의 구조체 변수 전달과 반환
*/
#include <stdio.h>
typedef struct
{
	int xpos;
	int ypos;
}Point;
void ShowPosition(Point pos)
{
	printf("[%d %d] \n", pos.xpos, pos.ypos);
}
Point GetCurrentPosition(void)
{
	Point cen;
	printf("현재 x-y좌표 입력: ");
	scanf("%d %d", &cen.xpos, &cen.ypos);

	return cen;
	// 구조체를 생성하여 멤버를 초기화하고 그 구조체를 반환(Point형 cen)
}
int main()
{
	Point curpos = GetCurrentPosition(); // GetCur-()함수의 반환값을 curpos로 복사
	ShowPosition(curpos);
	/* 29-30 == ShowPosition(GetCurrentPosition());
	구조체 변수 curpos가 ShowPosition 함수의 인자가 됨. */
	return 0;
}



/*
구조체 멤버로 선언된 배열의 복사
*/
#include <stdio.h>
typedef struct
{
	char name[20];
	char phoneNum[20];
	int age;
}Person;
void ShowPersonInfo(Person man)
{
	printf("name: %s \n", man.name);
	printf("phone: %s \n", man.phoneNum);
	printf("age: %d \n", man.age);
}
Person ReadPersonInfo()
{
	Person man;
	printf("name? ");
	scanf("%s", man.name);

	printf("phone number? ");
	scanf("%s", man.phoneNum);
	printf("age? ");
	scanf("%d", &man.age);
	return man;
}
int main()
{
	Person Man = ReadPersonInfo();
	// ReadPer-함수를 호출하면 구조체 변수 man에 값이 담긴다. 반환된 man은 메인함수의 구조체 변수 Man에 복사된다.
	ShowPersonInfo(Man);
	return 0;
}


/*
구조체 변수를 대상으로 하는 Call-by-ref.
*/
#include <stdio.h>
typedef struct
{
	int xpos;
	int ypos;
}Point;
void OrgSymTrans(Point *ptr) // 원점대칭이동
{
	ptr->xpos = (ptr->xpos)*-1;
	ptr->ypos = (ptr->ypos)*-1;
}
void ShowPosition(Point pos)
{
	printf("[%d, %d] \n", pos.xpos, pos.ypos);
}
int main()
{
	Point pos = { 7,-5 };
	printf("원래 값 "); ShowPosition(pos);
	OrgSymTrans(&pos);
	printf("원점 대칭이동 "); ShowPosition(pos);
	OrgSymTrans(&pos);
	printf("원점 대칭이동 "); ShowPosition(pos);
	return 0;
}


Output:
1
2
3
원래 값 [7, -5] 
원점 대칭이동 [-7, 5] 
원점 대칭이동 [7, -5] 


/*
구조체 변수간 대입연산 (멤버 대 멤버 복사)
*/
#include <stdio.h>
typedef struct
{
	int xpos;
	int ypos;
}Point;
void ShowPosition(Point pos)
{
	printf("[%d, %d] \n", pos.xpos, pos.ypos);
}
int main()
{
	Point pos1 = { 7,-5 };
	Point pos2;
	pos2 = pos1; // pos1에서 pos2로 대입연산(멤버 대 멤버 복사)
	printf("pos1 size: %d \n", sizeof(pos1));
	ShowPosition(pos1);
	printf("pos2 size: %d \n", sizeof(pos2));
	ShowPosition(pos2);
	return 0;
}


Output:
1
2
3
4
pos1 size: 8 
[7, -5] 
pos2 size: 8 
[7, -5] 



/*
구조체 변수를 대상으로 하는 +,- 연산
*/
#include <stdio.h>
typedef struct
{
	int xpos;
	int ypos;
}Point;
Point AddPoint(Point pos1, Point pos2)
{
	Point pos_Sum = { pos1.xpos + pos2.xpos, pos1.ypos + pos2.ypos };
	return pos_Sum;
}
Point MinPoint(Point pos1, Point pos2)
{
	Point pos_Min = { pos1.xpos - pos2.xpos, pos1.ypos - pos2.ypos };
	return pos_Min;
}
void ShowPosition(Point pos)
{
	printf("[%d %d] \n", pos.xpos, pos.ypos);
}
int main()
{
	Point pos1 = { 7,-5 };
	Point pos2 = { 2,9 };
	Point result;
	result = AddPoint(pos1, pos2);
	ShowPosition(result);

	result = MinPoint(pos1, pos2);
	ShowPosition(result);
	return 0;
}


Output:
1
2
[9 4] 
[5 -14] 



/*
구조체 두 변수를 대상으로 저장된 값을 바꿔주는 함수를 정의하고 이를 호출하는 예제 작성
*/
#include <stdio.h>
typedef struct
{
	int xpos;
	int ypos;
}Point;

void SwapPoint(Point *ptr1, Point *ptr2)
{
	Point temp = *ptr1;
	*ptr1 = *ptr2;
	*ptr2 = temp;
}

int main()
{
	Point pos1 = { 2, 4 };
	Point pos2 = { 5, 7 };
	printf("pos1 : [%d %d] ", pos1.xpos, pos1.ypos);
	printf("pos2 : [%d %d] \n", pos2.xpos, pos2.ypos);
	SwapPoint(&pos1, &pos2);
	printf("pos1 : [%d %d] ", pos1.xpos, pos1.ypos);
	printf("pos2 : [%d %d] \n", pos2.xpos, pos2.ypos);

	return 0;
}


Output:
1
2
pos1 : [2 4] pos2 : [5 7] 
pos1 : [5 7] pos2 : [2 4] 

/*
구조체를 통해 연관있는 데이터를 하나로 묶을 수 있는 자료형을 정의,
데이터 표현 및 관리가 용이해진다.
*/
#include <stdio.h>
typedef struct
{
	char name[20];
	char num[20];
	char major[20];
}Student;
void ShowStudent(Student *ptr)
{
	printf("이름 : %s \n", ptr->name);
	printf("학번 : %s \n", ptr->num);
	printf("전공 : %s \n", ptr->major);
}
int main()
{
	Student arr[3];
	int i;
	for (i = 0; i < 3; i++)
	{
		printf("이름 : "); scanf("%s", arr[i].name);
		printf("학번 : "); scanf("%s", arr[i].num);
		printf("전공 : "); scanf("%s", arr[i].major);
	}
	puts("");
	for (i = 0; i < 3; i++)
		ShowStudent(&arr[i]);
	return 0;
}

/*
중첩된 구조체의 정의
Point 구조체(x, y pos), Circle 구조체(Point cen, double rad)
center, radius를 입력받는 함수, 보여주는 함수를 정의하고 메인함수에서 출력
*/
#include <stdio.h>
typedef struct
{
	int xpos;
	int ypos;
}Point;
typedef struct
{
	Point cen;
	double rad;
}Circle;
Circle GetCircleInfo(void)
{
	Circle cir;
	printf("원의 중심 입력: ");
	scanf("%d %d", &cir.cen.xpos, &cir.cen.ypos);
	printf("반지름 입력: ");
	scanf("%lf", &cir.rad);
	return cir;
}
void ShowPosition(Circle cir_info)
{
	puts("");
	printf("원의 중심 : [%d %d] \n", cir_info.cen.xpos, cir_info.cen.ypos);
	printf("반지름 : %g \n", cir_info.rad);
}
int main()
{
	Circle Cir = GetCircleInfo();
	ShowPosition(Cir);

	return 0;
}


/*    ul (0, 0)    (100, 0)
(0, 100) (100, 100) lr
Rectangle 구조체 변수를 인자로 전달받아 직사각형 넓이를 계산해서 출력하는 함수,
직사각형 네 점의 좌표정보 출력 함수 각각 정의.
Rectangle 변수내에는 두 점의 정보만 존재 (좌표평면상 직사각형을 표현하기 위해 필요한 점의 갯수는 ul, lr 2개만 있으면 되므로)
*/
#include <stdio.h>
typedef struct
{
	int xpos;
	int ypos;
}Point;

typedef struct
{
	Point ul;	// upper left
	Point lr;	// lower right
}Rectangle;

void ShowRecArea(Rectangle rec)
{
	printf("넓이 : %d \n",
		(rec.lr.xpos - rec.ul.xpos)*(rec.lr.ypos - rec.ul.ypos));	// (가로) * (세로)
}

void ShowRecPos(Rectangle rec)
{
	printf("좌 상단: [%d %d] \n", rec.ul.xpos, rec.ul.ypos);
	printf("좌 하단: [%d %d] \n", rec.ul.xpos, rec.lr.ypos);
	printf("우 상단: [%d %d] \n", rec.lr.xpos, rec.ul.ypos);
	printf("우 하단: [%d %d] \n", rec.lr.xpos, rec.lr.ypos);
	/*(1,1)	(4,1)
	(1,4)	(4,4)*/
}

int main()
{
	Rectangle rec1 = { { 1,1 },{ 4,4 } };
	Rectangle rec2 = { { 0,0 },{ 7,5 } };
	ShowRecArea(rec1);
	ShowRecPos(rec1);

	ShowRecArea(rec2);
	ShowRecPos(rec2);
	return 0;
}


Output:
1
2
3
4
5
6
7
8
9
10
넓이 : 9 
좌 상단: [1 1] 
좌 하단: [1 4] 
우 상단: [4 1] 
우 하단: [4 4] 
넓이 : 35 
좌 상단: [0 0] 
좌 하단: [0 5] 
우 상단: [7 0] 
우 하단: [7 5] 


/*
공용체의 필요성
*/
#include <stdio.h>
typedef struct // 상, 하위 각 2바이트
{
	unsigned short upper;
	unsigned short lower;
}UpLowShort;
typedef union uniBuf
{
	int iBuf;
	char arrBuf[4]; // 아스키 코드 1바이트씩 뽑아내기 위한 배열
	UpLowShort ULBuf;
}UniBuf;
int main()
{
	UniBuf buf;
	printf("정수 입력: ");
	scanf("%d", &(buf.iBuf)); // int형 정수 입력받음
	printf("상위 2바이트 : %u \n", buf.ULBuf.upper);
	printf("하위 2바이트 : %u \n", buf.ULBuf.lower);
	printf("최상위 1바이트 아스키 코드: %c \n", buf.arrBuf[0]);
	printf("최하위 1바이트 아스키 코드: %c \n", buf.arrBuf[3]);
	return 0;
}

// 열거형의 정의와 변수 선언
#include <stdio.h>
typedef enum syllable
{
	Do = 1, Re = 2, Mi = 3, Fa = 4, So = 5, La = 6, Ti = 7
} Syllable;
void Sound(Syllable sy)
{
	switch (sy)
	{
	case Do:
		puts("도는 하얀 도라지 ♪"); return;
	case Re:
		puts("레는 둥근 레코드 ♩"); return;
	case Mi:
		puts("미는 파란 미나리 ♩♪"); return;
	case Fa:
		puts("파는 예쁜 파랑새 ♪♭"); return;
	case So:
		puts("솔은 작은 솔방울 ♩♪♪"); return;
	case La:
		puts("라는 라디오고요~ ♪♩♭♩"); return;
	case Ti:
		puts("시는 졸졸 시냇물 ♩♭♩♪"); return;
	}
	puts("다 함께 부르세~ 도레미파 솔라시도 솔 도~ 짠~");
}
int main(void)
{
	int tone; // == Syllable tone;
	for (tone = Do; tone <= Ti; tone++)
		Sound(tone);
	return 0;
}


Output:
1
2
3
4
5
6
7
도는 하얀 도라지 ♪
레는 둥근 레코드 ♩
미는 파란 미나리 ♩♪
파는 예쁜 파랑새 ♪♭
솔은 작은 솔방울 ♩♪♪
라는 라디오고요~ ♪♩♭♩
시는 졸졸 시냇물 ♩♭♩♪


열거형 상수는 0부터 시작해서 1씩 증가하는 형태로 결정된다.

enum Tone {Do, Re, Mi, Fa};

enum Tone {Do=0, Re=1, Mi=2, Fa=3};    // 명시하지 으면 0부터 시작


enum Tone {Mi=3, Fa, So=5, La};

enum Tone {Mi=3, Fa=4, So=5, La=6};    // 자동 할당, 앞서 선언된 상수보다 1이 증가된 값이 할당된다.


필요하면 

enum {Do=1, Re=2, Mi=3, Fa=4, So=5, La=6, Ti=7};

과 같이 변수 선언없이 열거형 상수로써 의미를 지니게 정의도 가능하다.


728x90