이번 포스팅에서는 구조체, Structure에 대해서 포스팅하겠습니다.
1. 구조체, Structure Type
2. 왜 사용하는가?
일단 직교좌표계에서 점을 표현하기 위해서는 원소가 2개가 필요하고, 다음과 같이 표현할 수 있습니다.
이를 C언어에서 표현을 한다라고 하면 다음과 같이 표현할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h> int main(void){ int x = 2; int y = 3; return 0; } |
이게 직교 좌표계의 한점을 C언어에서 표현한 방법입니다.
그럼 직교 좌표계에서 여러점을 동시에 표현한다고 해봅시다.
그럼 이렇게 표현될 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <stdio.h> int main(void){ int x_1 = 0; int y_1= 0; int x_2 = 1; int y_2= 1; int x_3 = 2; int y_3= 2; int x_4 = 3; int y_4= 3; int x_5 = 4; int y_5= 4; return 0; } |
바뀐 코드를 보면 해당 점마다 변수 이름이 모두 다르기 때문에 접근할 때마다 변수 이름을 하나하나씩 써야한다는 불편한 점이 있습니다.
이는 for문 같은 반복문을 쓸 때, 너무 힘이 듭니다.
자 그럼 이걸 배열을 써서 다음과 같이 만들어봅시다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> int main(){ int x[5]; int y[5]; int i; for(i=0; i < 5; i++){ x[i] = i y[i] = i } } |
이런 형태로 바꿀 수 있습니다.
그래도 뭔가 불편합니다. 그냥 이렇게 추상적으로 int x, int y로 표현하는 것보다 이건 좌표야! 라고 표현할 수 있는 무언가가 필요할 것 같습니다.
이럴 때, 쓰는 것이 구조체입니다.
3. 어떻게 쓰는가?
1. main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> #include <string.h> struct coordinate{ char tag[100]; double x; double y; }; int main(void){ struct coordinate coord; coord.x = 1.0; coord.y = 1.0; strcpy(coord.tag, "Quadrant 1"); printf("coord.tag: %s,\tcoord.x: %f,\t coord.y: %f\n", coord.tag, coord.x, coord.y); return 0; } |
2. Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | VPATH=./ EXEC=main OBJDIR=./ CC=gcc CFLAGS=-Wall -Wfatal-errors OBJ=main.o OBJS = $(addprefix $(OBJDIR), $(OBJ)) DEPS = $(wildcard ./*.h) Makefile $(EXEC): $(OBJS) $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(OBJDIR)%.o: %.c $(DEPS) $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ .PHONY: clean clean: rm -rf $(OBJS) $(EXEC) |
main.c 코드를 봅시다.
처음에 구조체를 선언법을 확인할 수 있습니다.
구조체를 선언하기 위한 예약어는 "struct"입니다. 해당 코드에서는 coordinate 라는 이름의 구조체를 선언했습니다.
그리고 그 구조체의 멤버로는 tag, x, y를 데이터 형태에 맞게 선언했습니다.
main함수에서는 구조체 사용법을 확인할 수 있습니다.
main 함수에서 해당 구조체 타입을 사용하기 위해서 struct coordinate coord라고 선언해주었습니다.
이는 coordinate라고 명명된 구조체 타입인 변수 coord를 선언한다라는 의미와 같습니다.
구조체 내부 변수의 접근 방법은 "." 연산자를 이용해서 접근합니다.
예제 코드에서 coord내부의 x라는 멤버 변수에 "."연산자로 접근하여 1.0이라는 숫자를 입력한 것을 확인 할 수 있습니다. (coord.x = 1.0;)
이것이 구조체의 제일 기본적인 사용법입니다.
자, 이제 구조체 사용에 대한 응용을 알아봅시다.
4. 응용 #1. typedef
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> #include <string.h> typedef struct coordinate{ char tag[100]; double x; double y; }COORDINATE; int main(void){ COORDINATE coord; coord.x = 1.0; coord.y = 1.0; strcpy(coord.tag, "Quadrant 1"); printf("coord.tag: %s,\tcoord.x: %f,\t coord.y: %f\n", coord.tag, coord.x, coord.y); return 0; } |
5. 응용 #2. 중첩 구조체
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <stdio.h> #include <string.h> typedef struct coord_information{ char information[100]; char quadrant; }COORD_INFORMATION; typedef struct coordinate{ COORD_INFORMATION info; double x; double y; }COORDINATE; int main(void){ COORDINATE coord; coord.x = 1.0; coord.y = 1.0; coord.info.quadrant='1'; strcpy(coord.info.information, "Coordinate system"); printf("coord.info.information: %s,\tcoord.info.quadrant: %c\n", coord.info.information, coord.info.quadrant); printf("coord.x: %f,\t coord.y: %f\n", coord.x, coord.y); |
6. 응용 #3. 함수 포인터
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <stdio.h> #include <string.h> typedef struct coordinate COORDINATE; struct coordinate{ float x; float y; void (*setCoordinate)(COORDINATE* coord, float, float); }; void set_coord(COORDINATE* coord, float x, float y){ coord->x = x; coord->y = y; } int main(void){ COORDINATE coord; coord.setCoordinate = set_coord; coord.setCoordinate(&coord,1.0, 1.0); printf("coord.x: %f,\t coord.y: %f\n", coord.x, coord.y); return 0; } |
7. 응용 #4. 초기화
1. Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | VPATH=./ EXEC=main OBJDIR=./ CC=gcc CFLAGS=-Wall -Wfatal-errors OBJ=main.o OBJS = $(addprefix $(OBJDIR), $(OBJ)) DEPS = $(wildcard ./*.h) Makefile $(EXEC): $(OBJS) $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(OBJDIR)%.o: %.c $(DEPS) $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ .PHONY: clean clean: rm -rf $(OBJS) $(EXEC) |
2. main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <stdio.h> #include <string.h> typedef struct coordinate{ char tag[100]; double x; double y; }COORDINATE; int main(void){ COORDINATE coord = {"Quadrant 1",1.0, 1.0}; printf("coord.tag: %s,\tcoord.x: %f,\t coord.y: %f\n", coord.tag, coord.x, coord.y); COORDINATE coord_1 = {"Quadrant 1",1.0, 1.0}; memset(&coord_1, 0, sizeof(COORDINATE)); printf("coord.tag: %s,\tcoord.x: %f,\t coord.y: %f\n", coord_1.tag, coord_1.x, coord_1.y); COORDINATE coord_2 = {.x = 1.0, .y = 1.0, .tag="Hello"}; printf("coord.tag: %s,\tcoord.x: %f,\t coord.y: %f\n", coord_2.tag, coord_2.x, coord_2.y); return 0; } |
3. 실행화면
구조체의 초기화는 여러가지 방식이 있는데, C89의 구조체 초기화, memset을 이용한 구조체 초기화, C99의 제한적인 초기화 방법이 있습니다.
구조체 coord의 초기화는 C89의 구조체 초기화이며, 구조체 선언시, 변수의 선언 순서대로 해당 값을 예제와 같이 입력해주면 됩니다.
구조체 coord1의 초기화는 memset함수를 이용한 초기화이며, memset(메모리 주소, 저장할 값, 해당 메모리 크기)순으로 입력하시면 됩니다.
예제에서 구조체 초기화시 tag = Quadrant 1, x = 1.0, y = 1.0으로 초기화해줬는데, memset을 이용하여 메모리를 0으로 바꾼것을 확인할 수
있습니다.
구조체 coord2의 초기화는 C99의 초기화로 구조체의 특정 변수들만 골라서 초기화할 수 있는 방법입니다.
8. 응용 #5 복사
1. Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | VPATH=./ EXEC=main OBJDIR=./ CC=gcc CFLAGS=-Wall -Wfatal-errors OBJ=main.o OBJS = $(addprefix $(OBJDIR), $(OBJ)) DEPS = $(wildcard ./*.h) Makefile $(EXEC): $(OBJS) $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(OBJDIR)%.o: %.c $(DEPS) $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ .PHONY: clean clean: rm -rf $(OBJS) $(EXEC) |
2. main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <stdio.h> #include <string.h> typedef struct coordinate{ double x; double y; }COORDINATE; int main(void){ COORDINATE coord; COORDINATE coord1; coord.x = 1.0; coord.y = 1.0; memcpy(&coord1, &coord, sizeof(COORDINATE)); printf("coord.x: %f,\t coord.y: %f\n", coord.x, coord.y); printf("coord1.x: %f,\t coord1.y: %f\n", coord1.x, coord1.y); return 0; } |
3. 실행화면
- 좌표를 나타내는 coordinate라는 구조체에 double형 변수 x,y를 정의합니다.
- typedef을 이용하여 struct coordinate를 COORDINATE라는 새로운 데이터형으로 만든다.
- COORDINATE라는 변수 coord, coord1을 생성한다.
- coord.x와 coord.y에 각각 1.0이라는 데이터를 입력한다.
- memcpy함수를 이용하여 coord의 구조체 내용을 coord1에 복사한다.
- 복사가 잘 되었는지 확인하기 위해서 해당 구조체 변수를 출력한다.
8. 응용 #5 함수 인자로 구조체 전달하기
1. Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | VPATH=./ EXEC=main OBJDIR=./ CC=gcc CFLAGS=-Wall -Wfatal-errors OBJ=main.o OBJS = $(addprefix $(OBJDIR), $(OBJ)) DEPS = $(wildcard ./*.h) Makefile $(EXEC): $(OBJS) $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(OBJDIR)%.o: %.c $(DEPS) $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ .PHONY: clean clean: rm -rf $(OBJS) $(EXEC) |
2. main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include <stdio.h> #include <string.h> typedef struct coordinate{ double x; double y; }COORDINATE; void func(COORDINATE coord); void _func(COORDINATE* coord); int main(void){ COORDINATE coord; coord.x = 1.0; coord.y = 1.0; printf("MAIN -> coord.x: %f,\t coord.y: %f\n", coord.x, coord.y); func(coord); printf("MAIN -> coord.x: %f,\t coord.y: %f\n", coord.x, coord.y); _func(&coord); printf("MAIN -> coord.x: %f,\t coord.y: %f\n", coord.x, coord.y); return 0; } void func(COORDINATE coord){ coord.x = 3.0; coord.y = 3.0; printf("FUCNTION -> coord.x: %f,\t coord.y: %f\n", coord.x, coord.y); } void _func(COORDINATE* coord){ coord->x = 5.0; coord->y = 5.0; printf("FUCNTION -> coord.x: %f,\t coord.y: %f\n", coord->x, coord->y); } |
3. 실행화면
- 좌표를 나타내는 coordinate라는 구조체에 double형 변수 x,y를 정의합니다.
- typedef을 이용하여 struct coordinate를 COORDINATE라는 새로운 데이터형으로 만듭니다.
- COORDINATE coord를 인자로 하는 함수 func와 COORDINATE* coord를 인자로 하는 함수 _func을 정의합니다.
- func은 내부 변수의 값을 각각 3.0으로 변경하고 이를 출력합니다.
- _func은 내부 변수의 값을 각각 5.0으로 변경하고 이를 출력합니다.
- COORDINATE라는 변수 coord 생성합니다.
- coord.x와 coord.y에 각각 1.0이라는 데이터를 입력합니다.
- coord의 내부 변수의 내용을 출력합니다.
- func의 파라미터로 coord를 줍니다.
- 해당 구조체 변수를 출력합니다.
- _func의 파라미터로 coord의 주소를 줍니다.(&coord)
- 해당 구조체 변수를 출력한다.
'IT > C|C++' 카테고리의 다른 글
[C] 외부 변수 참조, extern (0) | 2017.05.01 |
---|---|
[C] #ifndef을 이용한 header 중복 방지 (0) | 2017.04.21 |
[C] 재귀 함수 Recursion function (0) | 2017.03.28 |
[MinGW/Eclipse c++] Compile Error (0) | 2016.06.06 |
[Eclipse C++]Install Eclipse c++/ Eclipse c++ 설치하기 (0) | 2016.06.06 |