제 24강) 구조체와 형식 정의 지정자 |
오늘은 C언어에서 포인터만큼 많이 쓰이는 구조체와 형식 정의 지정자에 대해서 알아봅니다.
1) 형식 정의 지정자(typedef) |
형식 정의 지정자는 말 그대로 "형식을 정의하는 지정자(별칭자)" 입니다.
자료형의 별명을 지어줄 수 있다. |
라고도 설명할 수 있습니다.
// 사용법
typedef 자료형 별명;
// 예)
typedef int INT;
typedef char* STRING;
typedef int* Int_Ptr;
사용법은 위와 같습니다.
자료형의 이름을 별명으로 부르게 됩니다.
간단한 예제를 통하여 익혀봅시다.
#include <stdio.h>
#include <stdlib.h>
typedef int* Int_Arr; // int* == Int_Arr
typedef char* String; // char* == String
int main(void)
{
int size;
printf("배열의 크기: ");
scanf("%d", &size);
Int_Arr arr = (Int_Arr)malloc(sizeof(int) * size);
// int* arr = (int*)malloc(sizeof(int) * size);와 같은 뜻입니다.
for (int i = 0; i < size; i++)
arr[i] = i;
printf("배열 arr: ");
for (int i = 0; i < size; i++)
{
printf("%d", arr[i]);
if (i == size - 1)
printf("\n");
else
printf(", ");
}
String str = "char*을 String이라는 별명으로!!";
// char* str = "char*을 String이라는 별명으로!!";와 같은 뜻입니다.
printf("str: %s\n", str);
free(arr);
return 0;
}
위의 예제에서는 int*을 Int_Arr, char*을 String이라는 별명을 지어 사용합니다.
그래서 13번줄은 14번줄과, 28번줄은 29번줄과 같은 뜻이 됩니다.
2) 구조체(struct) |
구조체는 정말 중요합니다.
여러 변수들 묶은 집합체이다. |
여러 변수들을 하나의 블록으로 묶어놓은 것을 뜻합니다.
이 구조체를 사용하면 여러 데이터를 한 번에 묶어버릴 수 있습니다.
포인터를 포함한 다양한 데이터를 한 번에 묶어서 사용할 수 있죠.
// 사용법
struct 구조체_이름
{
자료형 변수이름1;
자료형 변수이름2;
...
자료형 변수이름n;
};
// 예)
struct Point
{
int xpos;
int ypos;
};
struct Person
{
char* name;
int age;
char sex;
};
사용법은 위와 같습니다.
위와 같이 선언된 구조체는
struct Point point;
struct Person person;
이렇게 사용할 수 있습니다.
이렇게 생성되어 변수화된 구조체를 구조체 변수라고도 합니다.
이제 구조체 내부에 선언된 변수에 접근하는 법을 알아봅시다.
위에서 선언한 구조체 변수 point와 person 내부에 선언되어 있는 변수에 접근하여 봅시다.
struct Point point;
struct Person person;
point.xpos = 5;
point.ypos = 6;
person.name = "홍길동";
person.age = 14;
person.sex = 'M';
바로 "->(빼기 + >)"로 접근을 하게 됩니다.
이렇게 따로따로 값을 나중에 넣어줄 수 있지만 처음부터 선언과 동시에 초기화하는 방법도 있습니다.
struct Point point = { 4, 5 };
이렇게 하면 됩니다.
(값은 변수가 선언된 순서대로 들어갑니다.)
(xpos = 4, ypos = 5)
예제를 통해서 위에서 배운 구조체에 대해서 다시 한 번 이해해봅시다.
(구조체를 살짝 변경하였습니다.)
#include <stdio.h>
#include <string.h>
struct Point
{
int xpos;
int ypos;
};
struct Person
{
char name[20]; // 문자열 변경을 위해서 포인터가 아닌 배열로 선언
int age;
char sex;
};
int main(void)
{
struct Point point;
struct Person person;
point.xpos = 5;
point.ypos = 6;
// 문자열 배열의 경우에는 대입연산으로 초기화가 불가능합니다.
// 대신에 strcpy를 이용하여 문자열을 넣어줄 수 있습니다.
strcpy(person.name, "홍길동");
person.age = 14;
person.sex = 'F';
printf("point 좌표: (%d, %d)\n", point.xpos, point.ypos);
printf("이름: %s\n", person.name);
printf("나이: %d\n", person.age);
printf("성별: %c\n\n", person.sex);
struct Point* point_ptr = &point;
struct Person* person_ptr = &person;
point_ptr->xpos = 12;
point_ptr->ypos = 11;
strcpy(person_ptr->name, "읭읭이");
person_ptr->age = 7;
person_ptr->sex = 'M';
printf("point 좌표: (%d, %d)\n", point.xpos, point.ypos);
printf("이름: %s\n", person.name);
printf("나이: %d\n", person.age);
printf("성별: %c\n\n", person.sex);
return 0;
}
위에서 배운 내용을 토대로 한 예제입니다.
일반적인 구조체변수에 접근하고 포인터 구조체변수에 접근하는 예제입니다.
추가적으로 구조체는
struct _Point
{
int xpos;
int ypos;
}Point;
이렇게도 선언이 가능합니다.
위에서 봤던 구조체와 같이 볼까요?
struct Point
{
int xpos;
int ypos;
};
struct _Point
{
int xpos;
int ypos;
}Point;
다른 점은 구조체의 이름이 2개인것 같은 느낌이 듭니다.
7번줄~11번줄과 같이 선언할 경우에는 구조체가 선언과 동시에 "Point"라는 변수를 만들어버립니다.
(_Point는 구조체의 이름, Point는 구조체를 바로 변수로 만든 이름)
즉, Point는 이미 변수화가 되어버린 것이지요.
struct Point
{
int xpos;
int ypos;
};
int main(void)
{
struct Point point;
point.xpos = 5;
point.ypos = 3;
...
}
struct _Point
{
int xpos;
int ypos;
}Point;
int main(void)
{
Point.xpos = 5;
Point.ypos = 3;
}
이렇다는 소리입니다.
만약에 17번~21번줄과 같이 선언하고 새로운 구조체변수를 만들고 싶다면
struct _Point
{
int xpos;
int ypos;
}Point;
int main(void)
{
Point.xpos = 5;
Point.ypos = 3;
struct _Point point2;
}
12번줄 처럼 만들어주시면 됩니다.
3) 구조체와 형식 정의 지정자 |
위에서 배운 방식으로 구조체를 사용하려면
struct Point
{
int xpos;
int ypos;
};
int main(void)
{
struct Point point;
...
}
이렇게 사용하게 됩니다.
만약에 구조체 이름이 길어지면 더 길어지겠죠.
그런데 이것을 typedef를 사용하면 조금이나마 짧게 사용할 수 있습니다.
typedef struct _Point
{
int xpos;
int ypos;
}Point;
struct 앞에 typedef를 붙여주면 됩니다.
이때 5번줄의 Point는 이 앞에서 배운 "선언과 동시에 변수 선언"과는 다른 뜻이 됩니다.
struct _Point를 Point라는 별명으로 부르겠다. |
라는 뜻이 됩니다.
#include <stdio.h>
typedef struct _Point
{
int xpos;
int ypos;
}Point;
int main(void)
{
Point point;
point.xpos = 5;
point.ypos = 6;
printf("point 좌표: (%d, %d)\n", point.xpos, point.ypos);
Point* point_ptr = &point;
point_ptr->xpos = 20;
point_ptr->ypos = 40;
printf("point 좌표: (%d, %d)\n", point.xpos, point.ypos);
return 0;
}
그래서 이렇게 사용할 수 있게 됩니다.
원래는 "struct _Point point"라고 선언했던 문장이 "Point point"로 간소화가 되었지요.
다음 시간에는 |
오늘은 struct를 배웠는데 이 struct에는 형제가 2명 더 있습니다.
바로 enum과 union이라는 것인데요.
다음시간에는 enum과 union에 대해서 알아봅니다.
'Study > C언어' 카테고리의 다른 글
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 26 [C언어의 파일 입출력1] (0) | 2018.10.28 |
---|---|
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 25 [공용체와 열거형(union, enum)] (0) | 2018.10.28 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 23 [메모리 구조와 메모리 할당, 배열 동적할당(malloc, realloc, calloc, free)] (0) | 2018.10.28 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 21 [다차원배열1 - 다차원배열의 기본(2차원, 3차원)] (0) | 2018.10.17 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 22 [다차원배열2 - 다차원배열과 포인터, 이중 포인터, 다중 포인터] (0) | 2018.10.17 |