[c언어 개념] #12 구조체, 구조체 배열, typedef, 공용체, 열거형
c언어 개념 정리와 문제 풀이를 통해 알고리즘 수업을 준비하는 과정입니다. 그동안 수강했던 c언어 수업 자료와 윤성우의 열혈 C 프로그래밍의 내용을 포함해 저에게 기록할 가치가 있는 내용이 담겨 있습니다.
구조체(structure)
구조체는 하나 이상의 변수를 묶어서 새로운 자료형을 정의하는 도구이다.
기본 자료형 변수를 묶어서 새로운 자료형을 만드는 것이고, '사용자 정의 자료형'이라 한다.
구조체를 통해서 연관 있는 데이터를 하나로 묶을 수 있는 자료형을 정의하면, 데이터의 표현 및 관리가 용이해지고, 그만큼 합리적인 코드를 작성할 수 있게 된다.
struct person
{
char name[20];
char phoneNum[20];
int age;
};
이렇게 하면 person이라는 이름의 구조체를 정의한 것이며 하나의 자료형을 정의한 것이다.
따라서 이제는 이 자료형을 대상으로 변수를 선언할 수 있다.
struct person me; // person 구조체의 변수인 me 선언
구조체 변수 안에 존재하는 멤버에 접근할 때는 '구조체 변수의 이름.구조체 멤버의 이름'으로 한다.
int main(void)
{
struct person woman1, woman2;
strcpy(woman1.name, "한호정");
strcpy(woman1.phoneNum, "010-0000-0000");
woman1.age = 23;
}
name, phoneNum은 배열이기 때문에 문자열 저장을 위해서는 strcpy 함수를 호출해야 한다.
int main(void)
{
struct person woman = {"한호정", "010-0000-0000", 23};
}
구초제 변수도 선언과 동시에 초기화할 수 있다. 멤버의 순서대로 초기화할 대상을 나열하면 된다.
초기화 과정에서는 문자열 저장을 위해 strcpy 함수를 호출하지 않아도 된다.
구조체 변수를 초기화하는 경우에도 배열의 초기화와 마찬가지로 초기화하지 않은 일부 멤버에 대해서는 0으로 초기화가 진행된다.
구조체 배열
#include <stdio.h>
struct point
{
int xpos;
int ypos;
};
int main(void)
{
struct point arr[3];
int i;
for(i=0; i<3; i++) {
scanf("%d %d", &arr[i].xpos, &arr[i].ypos);
}
}
point형 구조체를 선언하고, 구조체 배열을 선언했다.
구조체 배열을 이루는 구조체 변수의 멤버를 대상으로 입력을 받았다.
int main(void)
{
struct person arr[3] = {
{"한호정", "010-0000-0000", 23},
{"한호정2", "010-0000-0002", 23},
{"한호정3", "010-0000-0003", 23},
};
}
person형 구조체로 배열을 선언했고 그 동시에 초기화를 하고 있다.
구조체 배열을 선언과 동시에 초기화할 때는 배열의 길이만큼 중괄호를 사용해 초기화 하면 된다.
구조체 변수와 포인터
struct point pos = {1, 2};
struct point * pptr = &pos;
구조체 포인터 변수 pptr은 구조체 변수를 가리키는 포인터이다.
포인터 변수 pptr은 구조체 변수 pos를 가리킨다.
#inclue <stdio.h>
struct point
{
int xpos;
int ypos;
};
struct circle
{
double radius;
struct point * center;
};
구조체의 멤버로 배열과 포인터 변수가 선언될 수 있다.
typedef 선언
typedef 선언은 "기존에 존재하는 자료형의 이름에 새 이름을 부여하는 것" 을 목적으로 하는 선언이다.
typedef int INT; // int의 또 다른 이름 INT를 부여
typedef name1 name2 name3; // 새 이름의 부여는 가장 마지막에 등장하는 단어 중심이다.
struct point
{
int xpos;
int ypos;
};
typedef struct point Point;
typedef struct point
{
int xpos;
int ypos;
} Point;
typedef를 이해했다면 위 코드를 이해할 수 있다.
윗 블록을 typedef를 이용해서 아래 블록처럼 선언할 수 있다. 구조체 변수를 선언할 때 struct를 생략할 수 있게 된다.
그리고 아래 블록처럼 정의가 되면 구조체의 이름인 point는 사실상 별 의미를 갖지 않게 된다.
구조체 변수를 선언할 때도 typedef에 의해 정의된 이름인 Point를 사용하기 때문에 구조체의 이름 생략도 가능하다.
typedef struct
{
int xpos;
int ypos;
} Point;
따라서 위와 같이 쓸 수 있다. 이때는 struct 선언을 사용한 구조체 변수 선언은 불가능한데 사실 그렇게 쓸 일 없다.
함수의 인자로 전달되고 return문에 의해 반환되는 구조체 변수
함수의 인자로 구조체 변수를 전달할 수 있고, 구조체 변수의 주소 값을 전달할 수도 있다.
함수의 매개변수 선언 시 구초제 변수를 선언하거나, 구조체 포인터 변수를 선언할 수 있다.
구조체 변수를 대상으로 가능한 연산
구조체 변수를 대상으로는 제한된 형태의 연산만 가능하다.
대입연산, 주소 값 반환 목적인 & 연산, 구조체 크기 반환하는 sizeof 정도의 연산만 허용된다.
구조체 변수를 대상으로 덧셈, 뺄셈 등의 산술 연산은 불가능하다. 멤버 하나씩 접근해서 함수를 정의해야 한다.
구조체 변수간 대입연산의 결과로 멤버 대 멤버의 복사가 이뤄질 수 있다.
구조체의 중첩
구조체 변수도 구조체의 멤버로 선언될 수 있다.
공용체
struct를 사용하면 구조체, union을 사용하면 공용체이다.
구조체 변수가 선언되면, 구조체를 구성하는 멤버는 각각 할당이 된다.
공용체 변수가 선언되면, 공용체를 구성하는 멤버는 각각 할당되지 않고,
그 중 크기가 가장 큰 멤버의 변수만 하나 할당되어 이를 공유하게 된다.
공용체의 유용함은 다양한 접근방식을 제공하는데 있다.
하나의 메모리 공간을 둘 이상의 방식으로 접근할 수 있다.
열거형
struct를 사용하면 구조체, union을 사용하면 공용체, syllable을 사용하면 열거형이다.
열거형도 구조체와 공용체와 마찬가지로 자료형을 정의하는 방법으로 사용된다.
열거형은 저장 가능한 값 자체를 정수의 형태로 결정한다. 변수에 저장 가능한 값들을 열거해 정의한다.
열거형의 유용함은 이름있는 상수의 정의를 통한 의미의 부여에 있다.
둘 이상의 연관있는 이름을 상수로 선언함으로써 프로그램의 가독성을 높이는데 있다.