수업 출처) 숙명여자대학교 소프트웨어학부 수업 "자료구조", 유석종 교수님
1. Structure 구조체
- 자료형이 상이한 여러 멤버들을 하나의 자료로 묶어서 처리할 수 있는 복합 자료형
1-1. 구조체 변수 선언
// ex1
struct student
{
int age;
int grade;
char major[20];
} kim, lee;
// ex2
struct
{
int age;
int grade;
char major[20];
} kim, lee;
// ex3
struct student
{
int age;
int grade;
char major[20];
};
struct student kim, lee;
세 가지 모두 kim과 lee라는 구조체 변수를 선언하는 문장이다.
첫 번째 방식과 같이 구조체의 이름을 줄 수 있고, 두 번째 방식과 같이 구조체 변수를 생성할 수 있다. 세 번째 방식은 구조체 변수를 struct 키워드를 이용해서 선언하는 방식이다.
- 구조체 변수를 통해서 멤버에 값 저장
student.grade = 3;
strcpy(kim.major, "Software Convergence");
이와 같이 "." 연산자를 사용한다.
1-2. 구조체 자료형 선언
- 일반적으로 구조체를 사용할 때에는 typedef와 함께 사용되는데, typedef 키워드는 struct student_type{...}와 같이 긴 자료형 이름을 student 로 대체하여 구조체 변수를 선언할 수 있게 해준다.
// ex1
typedef struct student_type
{
char name[10];
int grade;
char major[20];
} student;
// ex2
typedef struct
{
char name[10];
int grade;
char major[20];
} student;
student kim, lee;
이처럼 struct만 쓴다면 } 이후 나오는 것은 그 구조체 자료형을 가진 "변수" 인 반면, typedef struct로 선언을 했을 때 } 뒤에 나오는 것은 구조체 "자료형" 이다.
1-3. 구조체 할당과 비교
- 할당
- 동일한 자료형의 구조체 변수 간에 직접적인 할당 명령문은 가능하다.
- (ex)
studnet kim, lee;
kim = lee;
- 비교
- 구조체 변수 간 직접 비교는 허용되지 않는다.
- 구조체 멤버 별로 비교해주어야 한다.
- (ex)
if (kim == lee) ... // 오류 !!
if (strcmp(kim.name, lee.name) ...
if (kim.age != lee.name) ...
if (kim.grade == lee.grade) ...
이런식으로 멤버별로 비교해주면 된다.
- 문자열 비교를 위해 사용된 strcmp 함수는 두 인자 값이 "다를" 경우 1을 반환한다.
1-4. 내장형 구조체
- 다른 구조체 변수를 멤버로 갖는 구조체
#include <stdio.h>
#include <string.h>
typedef struct Contact_type
{
char phone[20];
char email[20];
char address[20];
} Contact;
typedef struct Student_type
{
char name[20];
int age;
char major[20];
int grade;
Contact contact;
} Student;
void main()
{
Student kim;
strcpy(kim.name, "ChulSoo Kim");
kim.age = 22;
strcpy(kim.major, "Software Convergence");
kim.grade = 3;
strcpy(kim.contact.phone, "010-3606-0418");
strcpy(kim.contact.email, "kim@naver.com");
strcpy(kim.contact.address, "Seoul, Korea");
}
student 구조체 안에 contact 구조체를 넣은 형태이다.
2. Pointer 포인터
- 메모리 주소를 값으로 갖는 변수
- 간접 참조를 통해 원본 데이터를 공유하거나 변경할 수 있다.
- call by reference, 연결리스트 동적 메모리 관리 등에 사용된다.
2-1. "&" 과 "*"
- &
- 모든 변수에 붙일 수 있는 "주소" 연산자이다.
- 해당 변수의 메모리 주소 값을 반환한다.
- *
- 사용되는 위치에 따라 의미가 달라진다.
- 반드시 포인터형 변수에만 적용해야 한다.
- int i =3, j;
- int *p;
- p = &i;
- i의 주소를 p에 할당한다.
- kim = *p;
- kim 변수에 p가 가리키는 주소에 저장된 "값"을 대입한다.
- *p = j;
- p가 참조하는 "공간"에 j의 값을 저장한다.
3. Array 배열
- 자료형이 동일한 원소들의 유한집합
- <index, value> → item
- 선언 이후 배열의 크기를 변경할 수 없다.
- 배열의 원소 수가 n개 라면 유효한 배열 인덱스의 범위는 [0, n-1] 이다.
- 배열의 첫 번째 원소인 A[0] 을 "시작 주소 (α)"라고 부른다.
이후 원소들은 연속적인 메모리 주소에 저장된다. (α + sizeof(data type))
- (ex) int → 4bytes
α = 100100 → 100104 → 100108 → ...
- 배열 이름 A는 시작 주소를 값을 갖고 있는 "포인터 상수"이다. 선언에 사용된 이름은 이후 다른 값(주소)을 가질 수 없다.
- A == &A[0] : A[0]의 주소
- *A == A[0] : A[0]의 값
3-1. 함수에 배열 전달
- 시작 주소를 가지고 있는 "배열 이름"만 전달하면 된다.
- 배열 포인터 관점에서는 call by value이지만, 배열의 관점에서는 call by reference 라고 볼 수 있다.
- int list[] == int *list
- 배열 이름 + 정수 → 첫번째 원소에서 정수의 원소 개수만큼 떨어져 있는 원소의 주소
- (ex) oneArray = 100 → oneArray + 1 = 104, oneArray +2 = 108
4. Polynomial 다항식
- 항들의 집합
- 다항식 추상자료형 연산자
- Zero()
- IsZero()
- Coef (poly, expon) : 계수 찾기
- Lead_Exp (poly) : 최고차항 지수
- Attach (poly, coef, expon) : 항 추가
- Remove (poly, expon)
- SingleMult (poly, coef, expon) : 다항식과 단항의 곱셈
- Add (poly1, poly2)
- Mult (poly1, poly2)
- (ex) 다항식 배열 선언
#define MAX_TERMS 50
struct polynomial
{
float coef;
int expon;
};
struct polynomial terms[MAX_TERMS];
int avail = 0;