참고자료 : chapter 9-1. 구조체 박종혁 Tel: 970-6702 Email: jhpark1@snut.ac.kr 한빛미디어 출처 : 뇌를자극하는 C프로그래밍, 한빛미디어 -1-
구조체의형선언과멤버참조 구조체는배열과달리다른형태의자료형도묶어서처리할수있다. 한학생과관련된여러형태의데이터를묶어서처리할수있으므로배열보다효율적이다. - 5 명의학생에대한학번과학점을처리하는예 학점순서로정렬하면학번배열도정렬해야한다. 한빛미디어 -2-
구조체는형틀을먼저선언한다. 구조체를사용하기위해서는먼저원하는구조체의형태를컴파일러에게알려줘야한다. - 학생구조체를선언하는예 새로만든구조체형으로변수를선언한다. 한빛미디어 -3-
구조체의변수는멤버를참조하여사용한다. 배열은배열요소의형태가같으므로주소계산에의해각멤버의참조가가능하지만구조체는각멤버의형태가다르므로멤버참조연산자 (.) 로직접멤버를참조해야한다. #include <stdio.h> struct student{ int num; double grade; ; int main() { struct student s1; s1.num=2; s1.grade=2.7; printf( 학번 : %d n, s1.num); printf( 학점 : %.1lf n, s1.grade); return 0; // 구조체변수선언 // 구조체멤버참조 한빛미디어 -4-
구조체에는다양한멤버를사용할수있다. 구조체의멤버로는배열, 포인터변수, 이미정의된다른구조체의변수등모든응용자료형을사용할수있다. 멤버로배열을사용하는예 struct profile{ int age; double height; char name[20]; ; struct profile pf; // 나이를저장할멤버 // 키를저장할멤버 // 이름을저장할멤버 // 구조체변수의선언 name 멤버의사용 strcpy(pt.name, 홍길동 ); printf( %s n, pf.name); 한빛미디어 -5-
구조체에는다양한멤버를사용할수있다. 멤버로포인터변수를사용하는예 struct profile{ int age; double height; char *np; ; struct profile pf; pf.np= 홍길동 ; // 나이를저장할멤버 // 키를저장할멤버 // 이름을연결할포인터변수멤버 // 구조체변수의선언 // 포인터변수멤버에문자열연결 - 포인터변수를멤버로사용하는경우키보드로부터문자열입력은불가능하다 ( 문자열을저장할기억공간이없다!). 한빛미디어 -6-
구조체에는다양한멤버를사용할수있다. 구조체의멤버로다른구조체의변수를사용하는예 struct student{ struct profile pf; int num; double grade; ; struct student s1; // 이미선언된구조체를멤버로사용 // 구조체변수의선언 - 구조체의멤버로구조체를사용한경우멤버참조연산자를두번사용하여멤버를참조해야한다. 한빛미디어 -7-
다양한멤버를가진구조체를사용한프로그램 #include <stdio.h> struct profile{ int age; double height; char *np; ; struct student{ struct profile pf; int num; double grade; ; int main() { struct student s1; s1.pf.age=23; s1.pf.height=187.5; s1.pf.np=" 홍길동 "; s1.num=5; s1.grade=4.4; printf(" 이름 : %s n", s1.pf.np); printf(" 나이 : %d n", s1.pf.age); printf(" 키 : %.1lf n", s1.pf.height); printf(" 학번 : %d n", s1.num); printf(" 학점 : %.1lf n", s1.grade); return 0; 한빛미디어 -8-
구조체변수의초기화 구조체변수도배열과같이중괄호를사용하여초기화한다. - profile 구조체변수를초기화하는예 struct profile{ int age; double height; char name[20]; ; // 나이를저장할멤버 // 키를저장할멤버 // 이름을저장할멤버 구조체의형틀선언, 변수선언, 초기화를동시에할수있다. 한빛미디어 -9-
학생데이터를구조체로처리하는프로그램예 - 세명의데이터중에서학점이가장높은학생의학번, 이름, 학점을출력한다. #include <stdio.h> struct student{ int num; char name[20]; double grade; ; int main() { struct student s1={315, " 홍길동 ", 2.4, // 구조체변수의선언과초기화 s2={247, " 이순신 ", 3.7, s3={330, " 세종대왕 ", 4.4; struct student max; // 학점이가장높은학생의데이터를저장할구조체변수 max=s1; // 처음에홍길동의학점이가장높다고가정한다. if(s2.grade > max.grade) max=s2; // 각학생의학점을비교하여학점이가장높은 if(s3.grade > max.grade) max=s3; // 학생의데이터가 max에저장되도록한다. printf(" 학번 : %d n", max.num); printf(" 이름 : %s n", max.name); printf(" 학점 : %.1lf n", max.grade); return 0; // 학생데이터에대한구조체선언 // 학번을저장할멤버 // 이름을저장할멤버 // 학점을저장할멤버 // 학점이가장높은학생의각데이터를출력한다. 한빛미디어 -10-
구조체는대입연산이가능하다. 배열은대입연산이불가능하다. int ary1[5]={10,20,30,40,50; int ary2[5]; ary2 = ary1; // 불가능하다. 각배열요소를일일이대입해야한다! 구조체변수는대입연산으로모든멤버들을복사할수있다. struct student s1={315, 홍길동, 2.4; struct student max; max=s1; 한빛미디어 -11-
구조체변수를함수의전달인자로사용하자. 구조체는대입연산이가능하므로함수의전달인자로줄수있다. - 최고학점의학생데이터를함수로출력해보자. 함수의호출 max_prn(max); // 구조체변수를전달인자로주고호출한다. 함수의정의 void max_prn(struct student max) // 매개변수는구조체변수를선언한다. { printf( 학번 : %d n, max.num); printf( 이름 : %d n, max.name); printf( 학점 : %d n, max.grade); 한빛미디어 -12-
구조체를리턴하는함수 구조체를사용하면포인터없이도두변수의값을바꿀수있다. - 로보트의양쪽시력을바꾸는프로그램예 #include <stdio.h> struct vision{ double left; double right; ; struct vision exchange(struct vision); int main() { struct vision robot; printf(" 로보트의시력을입력하세요 ( 좌, 우 ) : "); scanf("%lf%lf", &robot.left, &robot.right); robot=exchange(robot); printf(" 바뀐로보트의시력 ( 좌, 우 ) : %.1lf, %.1lf n", robot.left, robot.right); return 0; struct vision exchange(struct vision robot) { double temp; temp=robot.left; robot.left=robot.right; robot.right=temp; return robot; 한빛미디어 -13-
구조체배열 구조체변수가많이필요하면배열로선언하여사용한다. - 주소록을만드는프로그램의예 (5 명의주소를저장할경우 ). struct address{ char name[20]; int age; char tel[20]; char addr[80]; ; // 이름을저장할멤버 // 나이를저장할멤버 // 전화번호를저장할멤버 // 주소를저장할멤버 한빛미디어 -14-
구조체배열의배열요소참조 구조체배열의참조된배열요소는구조체변수이므로실제데이터를저장하기위해서는다시멤버를참조해야한다. - list 배열의네번째배열요소의 age 멤버를참조할때 - list 배열의네번째배열요소의모든멤버에값을저장 strcpy(list[3].name, 홍길동 ); list[3].age=23; strcpy(list[3].tel, 012-345-6789 ); strcpy(list[3].addr, 울릉도동남쪽외로운섬독도 ); 한빛미디어 -15-
구조체배열의초기화 배열의초기화방법을그대로적용한다. 단, 배열의요소가구조체이므로각각의초기값은구조체초기화형식을사용한다. - list 배열의초기화 struct address list[5] = { { 홍길동, 23, 012-345-6789, 울릉도독도, { 이순신, 35, 111-222-3333, 서울건천동, { 장보고, 19, 222-333-4444, 완도청해진, { 유관순, 15, 333-444-5555, 충남천안, { 안중근, 45, 444-555-6666, 황해도해주 ; 한빛미디어 -16-
구조체배열을초기화하고출력하는예 - 배열요소의값을반복문으로출력한다. #include <stdio.h> struct address { char name[20]; int age; char tel[20]; char addr[80]; ; int main() { struct address list[5]={{" 홍길동 ", 23, "012-345-6789", " 울릉도독도 ", {" 이순신 ", 35, "111-222-3333", " 서울건천동 ", {" 장보고 ", 19, "222-333-4444", " 완도청해진 ", {" 유관순 ", 15, "333-444-5555", " 충남천안 ", {" 안중근 ", 45, "444-555-6666", " 황해도해주 "; int i; for(i=0; i<5; i++){ // 배열요소가 5개이므로 5번반복 printf("%10s%5d%15s%20s n", list[i].name, list[i].age, list[i].tel, list[i].addr); return 0; 한빛미디어 -17-
구조체포인터 구조체변수도하나의변수이므로포인터를구하여사용할수있다. struct score{ int kor, eng, mat; ; // 같은자료형의멤버는함께선언할수있다. struct score a={90, 80, 70; // 구조체변수의선언과초기화 구조체포인터변수를선언하고포인터를저장하자. 한빛미디어 -18-
구조체포인터변수를사용한멤버의참조 포인터변수로멤버를참조하기전에먼저구조체변수를참조한다. - 멤버참조연산자 (.) 가참조연산자 (*) 보다우선순위가높으므로괄호가필요하다. #include <stdio.h> struct score{ int kor, eng, mat; ; // 구조체의형틀선언 int main() { struct score a={90, 80, 70; struct score *sp=&a; printf( 국어 : %d n, (*sp).kor); printf( 영어 : %d n, (*sp).eng); printf( 수학 : %d n, (*sp).mat); return 0; // 구조체변수의선언과초기화 // 포인터변수에포인터저장 // 포인터변수로구조체변수의 // 각멤버를참조하여출력한다. 한빛미디어 -19-
간접멤버참조연산자 (->) 포인터변수가가리키는구조체변수의멤버를간단히참조할때간접멤버참조연산자 (->) 를사용한다. - list 구조체배열의데이터를출력하는함수를만들자. struct address list[5] = { ; list_prn(list); // list 는구조체배열의배열명 // 배열명을주고함수를호출한다. 한빛미디어 -20-
간접멤버참조연산자 (->) 구조체배열의배열명은첫번째구조체를가리키는포인터이므로배열명을받는매개변수는구조체포인터변수이어야한다. void list_prn(struct address *lp) { int i; for(i=0; i<5; i++){ printf( %10s%5d%15s%20s n, lp[i].name, lp[i].age, lp[i].tel, lp[i].addr); 매개변수 lp가구조체포인터변수이므로간접멤버참조연산자로멤버를참조할수있다. // 배열표현을포인터표현으로바꾼다. // 간접멤버참조연산자를사용한다. 한빛미디어 -21-
공용체 공용체는모든멤버가하나의기억공간을공유하며기억공간의크기는멤버중에서크기가가장큰멤버로결정된다. union student{ int num; double grade; ; // union 예약어를사용하여선언한다. union student s1; // 공용체변수의선언 공용체의멤버참조, 배열, 포인터의사용은구조체와같다. 단, 초기화할때는첫번째멤버만초기화가가능하다. union student s1 = {315; // 첫번째멤버인학번만초기화가능하다. 한빛미디어 -22-
공용체의장단점 공용체는모든멤버가하나의기억공간을공유하므로메모리를절약할수있지만다른멤버에의해서데이터가변질될위험이있다. #include <stdio.h> union student{ int num; double grade; ; int main() { union student s1={315; printf(" 학번 : %d n", s1.num); s1.grade=4.4; printf(" 학점 : %.1lf n", s1.grade); printf(" 학번 : %d n", s1.num); return 0; 출력결과 학번 : 315 학점 : 4.4 학번 : -1717986918 학번의초기값이학점멤버에의해서변질되었다. 한빛미디어 -23-
열거형 열거형은기억공간에저장될데이터의집합을정의한다. 열거형은읽기쉬운프로그램을작성하는데도움이된다. #include <stdio.h> enum season {spring, summer, fall, winter; int main() { enum season ss; // 열겨형변수선언 char *cp; // 문자열을저장할포인터변수 ss=spring; // 열거멤버의값을변수에대입 switch(ss){ case spring: cp="inline"; break; case summer: cp="swimming"; break; case fall: cp="trip"; break; case winter: cp="skiing"; break; printf(" 나의레저활동 => %s n", cp); return 0; 한빛미디어 -24-
typedef 를사용한형재정의 typedef 를사용하여응용자료형을간단하게사용할수있다. Student s1; // 재정의된자료형으로간단하게구조체변수선언 형선언과동시에재정의하는방법도가능하다. typedef struct { int num; double grade; Student; // 재정의될것이므로자료형의이름이필요없다. // 새로운자료형의이름을바로적어준다. 한빛미디어 -25-
typedef 를사용한프로그램예 #include <stdio.h> typedef struct { int num; double grade; Student; void data_prn(student *); int main() { Student s1={315, 4.2; data_prn(&s1); return 0; // 구조체의선언과동시에자료형의재정의한다. // 함수의선언, 매개변수는 Student형의포인터변수 // Student형의변수선언과초기화 // Student 변수의포인터를전달한다. void data_prn(student *sp) { printf(" 학번 : %d n", sp->num); printf(" 학점 : %.1lf n", sp->grade); // Student 형을가리키는포인터변수 // 구조체포인터변수로멤버참조하기 한빛미디어 -26-