차례: -struct -struct형 pointer 변수 -linked list
여러개의 데이터 형을 모아 하나의 데이터 타입으로 만들수 이는 사용자 정의형 데이터 타입이다.형식은--
두 개의 멤버 데이터 a 와 b 를 모아서 struct s 형 데이터 형으로 만드는 형식은
이 struct s 형 데이터 타입을 가지는 변수를 선언struct s // s 는 tag name 으로 사용자 맘대로 이름을 줄수 있다. { int a; char b; }; //strcut s 형 테이터 타입은 2 개의 멤버 a,b 를 가진다.struct s k; // 변수 k 는 struct s 형 테이터 타입이다. --------(보기) 다음과 같이 struct 형이 선언된 경우의 메모리 맵을 그려보자.
struct info { char a[3]; int b; float c; }; struct info k[3];풀이---struct info 데이터 타입은 3 개의 멤버 a,b,c 를 가지고 멤버 a 는 배열 멤버이다.
(유제) 메모리 맵을 그려보자.
struct s { char *p; int ia[3]; }; struct s k[2];(1) .(dot) 연산자
struct 변수는 여러개의 멤버를 가지기에 여러개 멤버중 특정 멤버를 가르키기 위해 . 연산자를 사용한다.형식은
struct형변수.멤버(보기) 그대로 입력 후 실행해 보자.#include < stdio.h > struct s { int a; char b; }; int main() { struct s k; k.a=20; k.b='A'; printf("%d %d\n",k.a,k.b); }(2) struct 에서 초기치 부여
(보기) 그대로 입력 후 실행 해보자.#include < stdio.h > struct s { char name[10]; int num; }; int main() { struct s k[3]={ {"lee",10} , {"park",20} , {"kim",30} }; int i; for(i=0; i < 3; i++) printf("%s , %d\n",k[i].name , k[i].num); }(유제) 다음은 k[0] 와 k[1] 을 교체하는 프로그램이다.#include < stdio.h > struct s { int a; char b; }; int main() { struct s k[]={ {10,'A'} , {20,'B'}}; 이 부분을 채우시오 for(i=0;i<2;i++) printf("%d %c\n",k[i].a,k[i].b); // 출력결과는 20 B 다음 줄에 10 A }(보기) 5 명의 이름과 국어 영어 점수를 입력 받은 후 총점을 구해서 출력하는 프로그램이다.#include < stdio.h > struct s { char name[20]; int kor,eng; int total; }; int main() { struct s hak[5]; for(i=0;i < 5; i++){ scanf("%s %d %d",hak[i].name , &hak[i].kor , &hak[i].eng); hak[i].total=hak[i].kor+hak[i].eng; } for(i=0;i < 5;i++) printf("%s %d %d %d\n",hak[i].name , hak[i].kor , hak[i].eng , hak[i].total); }(3) 멤버끼리의 연산...연산자 overloading
struct s { int m; int n; }; struct s a,b;두 struct 변수 a , b 에서a = b;는 어떻게 움직이는가? 이는 b 의 멤버가 a 의 멤버로 각각 대입된다.다음 프로그램은 어떻게 움직일까?
#include <stdio.h> struct s { int m,n; }; int main() { struct s p={1,2},q={3,4},r; r = p + q; printf("%d %d\n",r.m,r.n); }각 멤버끼리 더해서 r 의 멤버에 각각 대입된다고 예상해 볼수 있지만 컴파일 오류를 발생 .이는 연산자 overloading 으로 해결할 수 있다.
#include < stdio.h > struct s { int m,n; // 연산자 오버로딩 멤버 함수 struct s operator+(struct s k) { struct s tmp; tmp.m = m + k.m; tmp.n = n + k.n; return tmp; } }; int main() { struct s p={1,2},q={3,4},r; r = p + q; printf("%d %d\n",r.m,r.n); }* 이 부분 더 알고자하면 연산자 오버로딩(operator loading)으로 검색해 보세요.2. struct 형 pointer 변수
(보기) 그대로 입력 후 실행해보자#include < stdio.h > struct s { int a; char b; }; int main() { struct s *p,ss; ss.a=10; ss.b='A'; p=&ss; (*p).a = 20; (*p).b = 'B'; printf("%d %c\n",ss.a , ss.b); }p 는 포인터 변수이므로 2 바이트를 확보 후 ss 의 변수의 주소를 p 에 대입한 후 *p 하면 ss 전체를 의미한다. *p.a 하면 (*p).a 라고 한 이유는 * 보다 . 연산자의 우선순위가 높기 때문에 *p.a 는 *(p.a) 로 인식하기 때문에 (*p).a 라 한다.
(*p).a 표현은 -> 연산자를 사용해서 p->a 로 사용가능하다.
(1) -> 연산자
struct 형 포인터 변수에서 어떤 멤버 변수를 선택할 때 (*변수).멤버 표기가 복잡해서 변수 -> 멤버 처럼 -> 연산자를 도입해서 사용한다.다음 두 가지 표기는 동일하다.
(보기) 그대로 입력 후 실행해보자.
- *(struct형포인터변수).멤버
- struct형포인터변수 -> 멤버
#include < stdio.h > struct s { int a; char b; }; int main() { struct s *p; p=(struct s*)calloc(1,sizeof(struct s)); p->a = 20; p->b = 'A'; printf("%d , %c",p->a , p->b); }
3. linked list
배열에서 모든 자료들은 한 곳에 모인 형태이고 , 링크트리스트는 자료들이 흩어져 있는 구조이다.링크트리스트 구조에서는 흩어져 있는 자료들의 다음 위치를 가르키는 주소가 필요하다. 즉 데이부와 다음 주로슬 가르키는 링크의 두가지 멤버가 필요한 구조이다.
링크트리스트 구조에서는 자료와 다음 데이터의 위치를 가르키는 두개의 멤버가 존재하므로 struct 문을 사용하여 구현할 수 있다.
즉
- 링크트리스트는 자료들이 흩어져 있는 구조
- 다음 데이터의 위치를 가르키는 링크부와 데이터가 필요하고
- 삭입과 삭제시 배열구조보다 월등한 효율을 보이고
- 이제 더 이상의 자료가 없는 것은 링크부에 '\0' 즉 NULL 문자로 끝을 알린다.
struct node { char data; struct node* link; };노드 하나의 구조는
첫 번째 데이터가 A 이고 다음이 B 다음이 C 데이터 인 경우의 링크트 구조를 도시하면
'A' 데이터 노드의 주소가 100 , 'B' 데이터 노드의 주소가 300 , 'C' 데이터 노드의 주소가 200 이라면
실제적으로 화살표가 의미하는 바는 아래그림가 같은 의미가 된다.
(보기1) 그림과 같은 간단한 형식의 링크 구조를 구현 해보자.
#include < stdio.h > struct node { char data; struct node* link; }; int main() { struct node *p; p=(struct node*)calloc(1,sizeof(struct node)); p->data='A'; p->link='\0'; printf("%c",p->data); }(보기2) 아래 그림과 같은 링크트 구조를 구현 해 보자.
#include < stdio.h > struct node { char data; struct node* link; }; int main() { struct node *head,*p,*q; char i; head=(struct node*)calloc(1,sizeof(struct node)); p=head; p->data='A'; p->link='\0'; for(i='B'; i <= 'Z' ;i++){ q=(struct node*)calloc(1,sizeof(struct node)); q->data=i; q->link='\0'; p->link=q; p=q; } //링크를 따라가면서 출력 p=head; while ( p != NULL ){ printf("%c",p->data); p=p->link; } }(유제1) 보기 2 에서 구축한 링크로 리스트 구조에서 데이터 'P' 를 삭제 후 전체 링크 구조를 출력하려 한다.
(유제2) 보기 2 에서 구축한 링크 구조에서 이 링크 구조를 뒤집어서 출력하려 고 한다.
출처: dovelet