• 검색 결과가 없습니다.

구조체와 함수

N/A
N/A
Protected

Academic year: 2022

Share "구조체와 함수"

Copied!
35
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

구조체와 함수

구조체를 함수의 인수로 전달하는 경우

구조체의 복사본이 함수로 전달되게 된다.

만약 구조체의 크기가 크면 그만큼 시간과 메모리가 소요된다.

int equal(struct student s1, struct student s2) {

if( strcmp(s1.name, s2.name) == 0 ) return 1;

else

return 0;

}

(2)

구조체와 함수

구조체의 포인터를 함수의 인수로 전달하는 경우

시간과 공간을 절약할 수 있다.

원본 훼손의 가능성이 있다.

int equal(struct student const *p1, struct student const *p2) {

if( strcmp(p1->name, p2->name) == 0 ) return 1;

else

return 0;

}

포인터를 통한 구조 체의 변경을 막는다.

(3)

구조체를 반환하는 경우

복사본이 반환된다.

struct student make_student(void) {

struct student s;

printf("나이:“);

scanf("%d", &s.age);

printf("이름:“);

scanf("%s", s.name);

printf("키:“);

scanf("%f", &s.grade);

return s;

}

구조체 s의 복사본 이 반환된다.

(4)

예제

#include <stdio.h>

struct vector { float x;

float y;

}; struct vector get_vector_sum(struct vector a, struct vector b);

int main(void)

{ struct vector a = { 2.0, 3.0 };

struct vector b = { 5.0, 6.0 };

struct vector sum;

sum = get_vector_sum(a, b);

printf("벡터의 합은 (%f, %f)입니다.\n", sum.x, sum.y);

return 0;

}

a

a + b

b

(5)

예제

struct vector get_vector_sum(struct vector a, struct vector b) { struct vector result;

result.x = a.x + b.x;

result.y = a.y + b.y;

return result;

}

벡터의 합은 (7.000000, 9.000000)입니다.

a a + b

b

(6)

공용체 (union)

공용체(union)

같은 메모리 영역을 여러 개의 변수가 공유

공용체를 선언하고 사용하는 방법은 구조체와 아주 비슷

union example {

char c;

// 같은 공간 공유

int i;

// 같은 공간 공유

};

(7)

예제

#include <stdio.h>

union example { int i;

char c;

};

int main(void)

{ union example v;

v.c = 'A';

printf("v.c:%c v.i:%i\n", v.c, v.i );

v.i = 10000;

printf("v.c:%c v.i:%i\n", v.c, v.i);

}

v.c:A v.i:65 v.c:□ v.i:10000

공용체 선언

공용체 변수 선언. char 형으로 참조.

int 형으로 참조.

(8)

ip 주소 예제

#include <stdio.h>

union ip_address {

unsigned long laddr;

unsigned char saddr[4];

};

int main(void)

{ union ip_address addr;

addr.saddr[0] = 1;

addr.saddr[1] = 0;

addr.saddr[2] = 0;

addr.saddr[3] = 127;

printf("%x\n", addr.laddr);

return 0;

}

7f000001

(9)

공용체에 타입 필드 사용

#include <stdio.h>

#include <string.h>

#define STU_NUMBER 1

#define REG_NUMBER 2

struct student { int type;

union {

int stu_number;

// 학번

char reg_number[15];

// 주민등록번호

} id;

char name[20];

(10)

공용체에 타입 필드 사용

void print(struct student s) {

switch(s.type) {

case STU_NUMBER:

printf("학번 %d\n", s.id.stu_number);

printf("이름: %s\n", s.name);

break;

case REG_NUMBER:

printf("주민등록번호: %s\n", s.id.reg_number);

printf("이름: %s\n", s.name);

break;

default:

printf("타입오류\n");

break;

}

}

(11)

공용체에 타입 필드 사용

int main(void) {

struct student s1, s2;

s1.type = STU_NUMBER;

s1.id.stu_number = 20070001;

strcpy(s1.name, "홍길동");

s2.type = REG_NUMBER;

strcpy(s2.id.reg_number, "860101-1056076");

strcpy(s2.name, "김철수");

print(s1);

print(s2);

}

학번 : 20070001 이름 : 홍길동

주민등록번호: 860101-1056076

이름: 김철수

(12)

열거형 (Enumeration)

 열거형(enumeration)이란 변수가 가질 수 있는 값들을 미리 열거해놓은 자료형

 (예) 요일을 저장하고 있는 변수는 { 일요일, 월요일, 화요일, 수요일, 목요일, 금요일, 토요일 } 중의 하나의 값만 가질 수 있다.

(13)

열거형의 선언

enum days { SUN, MON, TUE, WED, THU, FRI, SAT };

태그 이름 값들을 나열

enum days today;

today = SUN; // OK!

열거형 변수 선언

(14)

열거형이 필요한 이유

다음과 같이 프로그램을 작성할 수 있다.

int today;

today = 0; // 일요일

today = 1; // 월요일

되도록 오류를 줄이고 가독성을 높여야 된다.

 0보다는 SUN라는 기호상수가 더 바람직하다. 의미를 쉽게 알 수 있기 때문이다.

 today에 9와 같은 의미없는 값이 대입되지 않도록 미리 차단하는 것도 필요하다.

(15)

열거형 초기화

enum days { SUN, MON, TUE, WED, THU, FRI, SAT };

// SUN=0, MON=1, ...

enum days { SUN=1, MON, TUE, WED, THU, FRI, SAT };

// SUN=1, MON=2, ...

enum days { SUN=7, MON=1, TUE, WED, THU, FRI, SAT=6 };// SUN=7, MON=1, ...

값을 지정하기 않으면 0부터

할당

(16)

열거형의 예

enum colors { white, red, blue, green, black };

enum boolean { false, true };

enum levels { low, medium, high };

enum car_types { sedan, suv, sports_car, van, pickup, convertible };

(17)

예제

#include

<stdio.h>

enum days { SUN, MON, TUE, WED, THU, FRI, SAT };

char *days_name[] = {

"sunday", "monday", "tuesday", "wednesday", "thursday", "friday",

"saturday"

};

int main(void) {

enum days d;

d = WED;

printf("%d번째 요일은 %s입니다\n", d, days_name[d]);

return 0;

}

3번째 요일은 wednesday입니다

(18)

열거형과 다른 방법과의 비교

정수 사용 기호 상수 열거형

switch(code) { case 1:

printf("LCD TV\n");

break;

case 2:

printf("PDP TV\n");

break;

}

#define LCD 1

#define PDP 2 switch(code) {

case LCD:

printf("LCD TV\n");

break;

case PDP:

printf("PDP TV\n");

break;

}

enum tvtype { LCD, PDP };

enum tvtype code;

switch(code) { case LCD:

printf("LCD TV\n");

break;

case PDP:

printf("PDP TV\n");

break;

} 컴퓨터는 알기 쉬우나 사람은

기억하기 어렵다 . 기호 상수를 작성할 때 오류를

저지를 수 있다 . 컴파일러가 중복이 일어나지 않

도록 체크한다 .

(19)

typedef 의 개념

(20)

typedef

 typedef은 새로운 자료형(type)을 정의(define)

 C의 기본 자료형을 확장시키는 역할

typedef old_type new_type;

typedef unsigned char BYTE;

기존의 자료형 새로운 자료형 새로운 자료형을 정의

(21)

typedef의 예

typedef unsiged char BYTE;

BYTE index;

// unsigned int index;와 같다.

typedef int INT32;

typedef unsigned int UINT32;

INT32 i;

// int i;와 같다.

UINT32 k;

// unsigned int k;와 같다.

(22)

struct point { int x;

int y;

};

typedef struct point POINT;

POINT a, b;

구조체로 새로운 타입 정의

구조체로 새로운 타입을 정의할 수 있다.

(23)

예제

#include <stdio.h>

typedef struct point { int x;

int y;

} POINT;

POINT translate(POINT p, POINT delta);

int main(void)

{ POINT p = { 2, 3 };

POINT delta = { 10, 10 };

POINT result;

result = translate(p, delta);

printf("새로운 점의 좌표는(%d, %d)입니다.\n", result.x, result.y);

return 0;

(24)

예제

POINT translate(POINT p, POINT delta) { POINT new_p;

new_p.x = p.x + delta.x;

new_p.y = p.y + delta.y;

return new_p;

}

새로운 점의 좌표는 (12, 13)입니다.

(25)

typedef과 #define 비교

이식성을 높여준다.

코드를 컴퓨터 하드웨어에 독립적으로 만들 수 있다

 (예) int형은 2바이트이기도 하고 4바이트, int형 대신에 typedef을 이용한 INT32나 INT16을 사용하게 되면 확실하게 2바이트인지 4바이트인지를 지정할 수 있다.

 #define을 이용해도 typedef과 비슷한 효과를 낼 수 있다. 즉 다음과 같이 INT32를 정의할 수 있다.

 #define UINT32 unsigned int

 typedef float VECTOR[2];// #define으로는 불가능하다.

문서화의 역할도 한다.

(26)

실습: 평점이 높은 학생 찾기

어느 학교나 학기가 끝나면 학과 내에서 가장 평점이

높은 학생을 선발하여서 장학금을 수여한다. 가장 평점이 높은 학생을 찾아서 학생의 이름과 학번, 평점을 화면에 출력하는 프로그램을 작성하여 보자.

평점이 가장 높은 학생은 (이름: 홍길동, 학번: 20120001, 평점: 4.200000)입니다.

(27)

힌트

학생에 대한 정보는 구조체를 이용하여서 표현한다.

학생들이 여러 명이므로 구조체의 배열을 사용하는 것이 좋겠다.

struct student { int number;

char name[20];

double grade;

};

struct student list[] = { { 20120001, “홍길동", 4.2 },

{ 20120002, “김철수", 3.2 },

(28)

소스

#include <stdio.h>

struct student { int number;

char name[20];

double grade;

};

struct student list[] = {

{ 20120001, "홍길동, 4.2 },

{ 20120002, "김철수, 3.2 },

{ 20120002, "김영희, 3.9 }

};

(29)

소스

int main(void) {

struct student super_stu;

int i, size;

size = sizeof(list)/sizeof(list[0]);

super_stu = list[0];

for(i=1; i< size; i++) {

if( list[i].grade > super_stu.grade ) super_stu = list[i];

}

printf("평점이 가장 높은 학생은 (이름%s, 학번%d, 평점%f)입니다\n",

super_stu.name, super_stu.number, super_stu.grade);

(30)

비트 단위 구조체 (bit-field structure)

 struct with bit-unit members

struct TagName {

DataType member_1: numberOfBits;

DataType member_2: numberOfBits;

}; ...

struct product { unsigned style : 3;

unsigned size : 2;

unsigned color : 1;

};

unsigned int

3 2 1

(31)

bit_field.c

1. // bit-field structure 2. #include <stdio.h>

3. struct product { 4. unsigned char 5. style : 3,

6. size : 2,

7. color : 3;

8. };

9. int main(void) 10. {

11. struct product p1;

12. p1.style = 5; p1.size = 3; p1.color = 6;

13. printf("sizeof(p1)=%d₩n", sizeof(p1));

14. printf("style=%d, size=%d, color=%d₩n", p1.style, p1.size, p1.color);

15. printf("p1=%x₩n ", p1);

16. return 0;

17. }

(32)

Example of Bit-field mapping

 Bit-field mapping in Little-Endian and Big-Endian

0x2000 0x2001 0x2002

0x2003 0x2000

0x2001 0x2002 0x2003

Big-Endian Byte Ordering, Bit-field Mapping

(Apple Mac)

Little-Endian Byte Ordering, Bit-field Mapping

(PC Intel CPU) struct BFU_32 {

unsigned char f1:3, f2:3,

f3:2;

char c;

unsigned short s1:3, s2:3,

s3:2, s4:3, s5:2, s6:3;

}; struct BFU_32 *pU32 = (struct BFU_32 *)0x2000;

0 7

f1 f2 f3

c

s1 s2 s3

s4 s5 s6

s6 s5 s4 s3 s2 s1

c

f3 f2 f1

7 0

(33)

Homework 8

8.1 복소수 계산을 위한 구조체 정의 (Struct MyCmplx)

1) 복소수는 실수부와 허수부를 가지며, c = real (실수부) + j imaginary(허수부) 로 표현된다. 복소수를 위한 구조체 struct Cmplx를 작성하라. 실수부와 허수부는 보다 높은 정밀도를 위하여 double 데이터 유형을 사용한다.

struct Cmplx { double real;

double imaginary;

double magnitude;

}

2) 복소수의 4칙 연산을 위한 함수를 정의하라.

- Cmplx cmplxAdd(Cmplx c1, Cmplx c2);

- Cmplx cmplxSubtract(Cmplx c1, Cmplx c2);

- Cmplx cmplxMultiply(Cmplx c1, Cmplx c2);

- Cmplx cmplxDivide(Cmplx c1, Cmplx c2);

3) 복소수 배열 (예: Cmplx cmplxs[6])을 정의하라.

(34)

4) 표준입력장치로 부터 4개의 double형 데이터를 입력받아, 두개의 복소수의 실수부와 허수부의 값으로 설정하라. 이들 두개의 복소수는 복소수 배열의 첫번째 두개의

복소수에 해당한다 (cmplxs[0], cmplxs[1]). 입력 포멧은 “rrr.ddd iii.ddd”를 사용하라.

5) 위에서 구현한 4개의 복소수 연산 함수를 사용하여, 표준 입력장치로 부터 입력을 받아 설정된 두개의 복소수 (cmplxs[0], cmplxs[1])의 addition, subtraction, multiplication 과 division을 계산하고, 그 결과를 각각 cmplxs[2], cmplxs[3], cmplxs[4], cmplxs[5]에 저장하라. 각 복소수의 크기 (magnitude) magnitude = sqrt (real^2 + imaginary^2) 공식을 사용하여 계산할 것.

6) 복소수 배열에 포함된 각 복소수 (cmplxs[0] ~ cmplxs[5])를 “rrr.ddd + j iii.ddd (magnitude mmm.ddd)” 양식으로 한줄에 복소수 1개씩을 출력하라.

7) 복소수 배열의 신속한 정렬을 위하여, 퀵정렬 함수 ( sortCmplx(Cmplx cmplxs[], int size))를 작성하라. 이 복소수 배열의 퀵정렬함수는 복소수 배열을 파라메터로 전달 받으며, 복소수 크기 (magnitude)값의 오름차순으로 정렬한다.

8) 정렬된 복소수 배열을 “rrr.ddd + j iii.ddd (magnitude mmm.ddd)” 양식으로

한줄에 복소수 1개씩을 출력하라.

(35)

8.2 구조체 Time을 사용하는 Clock system

1) 시간을 나타내기 위하여, hour, minute, 및 second를 포함하는 구조체 Time을 작성하라.

struct Time { int hour;

int min;

int sec;

};

2) 표준 입력 장치로 부터 3개의 정수를 입력 받아, 이를 각각 시, 분, 초의 값으로 설정하라. 예를 들 어, “10 5 30” 로 입력된 정수는 구조체 Time 변수의 “10시 5분 30초”로 설정된다. 시간을 나타 내는 값은 0시 ~ 23시의 값을 가지도록 할 것.

3) 구조체 Time 변수의 값을 “hh:mm:ss” 양식으로 출력하는 함수를 작성하라. 구조제 Time 변수 는 “00:00:00” ~ “23:59:59” 구간의 값을 가진다.

4) 구조체 Time 변수 값을 지정된 초단위로 증가하는 함수 “void incrementTime(Time *, int)”

를 작성하라. 표준 입력 장치로 부터 정수를 입력 받아, 위 2)에서 초기화 설정된 구조체 Time 변 수의 값을 증가시켜라. 분과 시는 60초와 60분 단위로 증가되어야 한다. 예를 들어, “23:59:59”

에 2 초를 더하면 “00:00:01”이 되어야 한다.

5) 두개의 구조체 Time 변수를 비교하는 “int timeCompare(const Time *tptr1, const Time

*tptr2)” 함수를 작성하라. 이 함수는 call-by-pointer로 (구조체 포인터)로 전달되는 두개의 시 간을 비교하여, 그 차이 (초 단위)를 반환한다. 반환 데이터 유형은 정수이며, 초단위 값을 나타낸 다. 위 2)에서 초기 설정된 시간 값과 4)에서 증가된 시간값을 비교하여, 그 차이를

timeCompare() 함수를 사용하여 계산하고, 그 결과를 반환하여, 정확한 계산이 이루어 졌는가

를 확인하라.

참조

관련 문서

 수퍼 시니어 트랜치(super senior tranche)라는 가장 등 급이 높은 트랜치는 가장 먼저 현금 지급이 완료되기 때 문에 위험이 가장 작음. 

또한 문화적 이질성이 높 은 국가에서는 다양한 소비자 계층에 부응하기 위한 더 높은 시장 세분화가 요구됨. 적대감이 높은 현지굮에 있어서는 적극 적인

시험 이후 설문 조사를 통해 자료를 수집 하였으며 , 설문지는 교육대상자의 심정지 상황에 대한 경험과 사전 심폐소생술 교육 경험 , 지식 및 교육 후 심 폐소생술

- 요즘 학생들에게 선호도가 높은 게임들의 목록을 작성하여 컴퓨터에 프로그램 등을 저장해 놓고 , 피실험자가 직접 게임을 선택, 수행하여 게임에 몰두할

어떤 목욕탕건물에서 가장 높은 곳에 있는 샤위꼭지까지의 높이가 지상에서 7m이다...

 상점에서 고객이 상품을 사고 돈을 냈을 경우에 거스름돈을 계산해주 는 프로그램을 작성하여 보자 .... 핵심예제

높은 가치를 느끼는 집단에는 높은 가격을 받는다.. 가격민감도가 낮은 집단에는

 When we refer to ‘blood sugar’, we actually mean the monosaccharide (simple sugar) glucose dissolved in