단순 연결리스트에 파일 입출력을 응용
위와 같은 형태의 연결리스트에 파일 입출력을 응용해본다.
연결리스트를 파일로 저장
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | void save_File() { FILE *fp; fp = fopen("DATA.DBF", "wb"); if (fp == NULL) { printf(" 오류 \n"); return; } cur = head->next; while (cur != NULL) { fwrite(cur, DATA_SIZE, 1, fp); // Data_SIZE는 pointer(*next)를 제외한 구조체 size cur = cur->next; } fclose(fp); } | cs |
파일을 읽어들여 연결리스트로 구성
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 | void load_File() { FILE *fp; fp = fopen("DATA.DBF", "rb"); Book *nN; if (fp == NULL) { printf(" 오류 \n"); return; } while (1) { nN = (Book*)calloc(1, sizeof(Book)); if (!fread(nN, Data_SIZE, 1, fp)) // 파일의 끝이면 { free(nN); break; } else if (head->next == NULL) { head->next = nN; } else { tail->next = nN; } tail = nN; nN->next = NULL; } fclose(fp); } | cs |
rb모드로 파일을 열고 리스트를 재구성하는 작업을 해준다.
malloc() 함수는 메모리를 할당후 초기화하지 않기 때문에 출력된 파일을 메모장으로 열어보면 데이터를 알아보기 힘들게 된다.
하지만 문자열의 끝은 NULL로 구분하게 되므로 콘솔환경의 파일 입출력시에는 아무 문제없다.
만약 식별하기 쉬운 파일 데이터를 원하면, 위와 같이 calloc함수를 통해 동적할당하면 된다. (calloc함수는 모든 비트를 0으로 초기화 http://wowcat.tistory.com/3001)
따로 파일을 읽어들이는 메뉴를 구성한다면 노드의 추가전에 남아있는 모든 노드를 제거하는 과정을 추가할 필요도 있겠다.
아래와 같이 리스트의 초기화 함수 호출후 load_File함수를 호출하도록 한다. 종료시에 save_File() 함수를 호출하거나 따로 메뉴를 구성하는 것도 좋겠다.
1 2 3 4 5 6 7 | int main() { list_init(); load_File(); (...) return 0; } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h> union smart { int A; short B; int C; char D; }obj; int main() { obj.A = 0x12345678; obj.B = 0x12345678; obj.C = 0x12345678; obj.D = 0x12345678; printf("Size of Smart: %d\n", sizeof(union smart)); printf("%x\n", obj.A); printf("%x\n", obj.B); printf("%x\n", obj.C); printf("%x\n", obj.D); return 0; } | cs |
위 공용체의 size는 4byte
Little Endian
78 | 56 | 34 | 12 |
obj.A=12345678 // int A
obj.B=5678 // short B
obj.C=12345678 // int C
obj.D=78 // char D
함수 포인터
: 함수를 가리키는 포인터
int SoSimple(int num1, int num2) { ....}
위 함수에 대한 함수 포인터 변수 선언
int (*fptr) (int, int);
함수 포인터 변수에 SoSimple 주소값 저장
fptr = SoSimple
이는 fptr(3, 4); // SoSimple(3, 4)와 동일한 결과
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> void Add(int n1, int n2) { printf("%d + %d = %d \n", n1, n2, n1 + n2); } int main() { int num1 = 10, num2 = 20; void(*fptr)(int, int) = Add; fptr(num1, num2); return 0; } | cs |
Output :
10 + 20 = 30
void형 포인터 변수는 어떠한 변수의 주소 값이든 담을 수 있지만(함수의 주소값도)
값의 변경이나 참조를 비롯한 어떤 포인터 연산도 불가
: type 정보가 없기 때문에 당연
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> void voidFunc(void) { printf("void ptr test\n"); } int main() { void(*fptr)(void) = voidFunc; fptr(); return 0; } | cs |
Output :
void ptr test
가변 인자 함수
num = Sum(3, 1, 2, 3); // 3은 이후에 전달되는 인자의 갯수 (1,2,3)
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> int Sum(int n, ...) // 가변 인자에 대한 선언 { printf("n=%d \n", n); return 0; } int main() { Sum(3, 1, 2, 3); return 0; } | cs |
Output :
n=3
가변 인자 함수의 호출을 통해 전달되는 인자 정보 추출
#include <stdarg.h>
1. 가변인자를 가리킬 수 있는 참조자 선언 : va_list
2. 참조자가 가변인자를 실제 참조 : va_start
3. 참조자를 통해 전달된 정보 추출 : va_arg
4. 참조자가 가변인자를 가리키지 않도록 해제 : va_end
Output :
3+5=2=10
22행 : (vlist, int) 첫번째 인자는 참조자 이름, 두번째 인자는 참조대상의 type
'코스웨어 > 16년 스마트컨트롤러' 카테고리의 다른 글
2016-11-05_조재찬_스터디일지_자료 구조-Stack (2) | 2016.11.05 |
---|---|
아두이노 부트로더 복구 (0) | 2016.10.27 |
2016.03.02 구조체와 응용 (0) | 2016.10.19 |
2016-10-13_조재찬_스터디일지_CPP-상속의 이해 (0) | 2016.10.13 |
2016-10-09_조재찬_ 프로젝트 일지_테트리스 게임 (4) (0) | 2016.10.09 |
2016-10-07_조재찬_ 프로젝트 일지_테트리스 게임 (3) (0) | 2016.10.07 |
2016-10-05_조재찬_ 프로젝트 일지_테트리스 게임 (2) (0) | 2016.10.05 |
2016-10-04_조재찬_ 프로젝트 일지_테트리스 게임 (0) | 2016.10.04 |