[yummyHitOS] 24 day (2017.08.14)

7 분 소요

안녕하세여!! 두 달 만에 찾아온 야미예여 ㅜㅜ 두 달이나 지났을 줄 상상도 못해써여!! 나이가 점점 빨리 먹어가고 있는 느낌이네여!?

저번에 말씀드린 강의계획을 실현하다 보니... 사람 모으기도 힘겹고 ㅜㅜㅠ 그래가지구 이것 저것 생각도 많구~ 사람 만날일두 많구~ 야근도 많구~ 일도 많구~ 뭔가 이것 저것 많아서 복받았네여!! 젠쟝...



오늘은 이런 식의 챕터가 되겠어요.. 나닛!? 뭔 설명이 2+2 알려주다가 증명식이...

우리가 오늘 할 챕터는 바로 제가 사랑하는 언어인 C언어의 기본 라이브러리 함수를 직접 구현하는 날이기 때문이예여!!

책에 나와 있듯이, fopen(), fread(), fwrite(), fseek(), fclose(), remove() 함수와 opendir(), readdir(), rewinddir(), closedir() 함수를 구현한대요!! 이것이 무엇을 의미하느냐!!


저희가 C언어에서 가장 먼저 선언하는 구문인 #include !! 이 지시어를 통해 stdio.h (studio 아니예용~ standard input/output header file 이랍니당!!) 헤더파일을 불러내 이 헤더파일 내 함수들을 사용하잖아여!?


stdio.h

※ stdio.h 헤더 파일 멤버 함수


함수 명 내용
fopen(), freopen() 파일을 읽거나 쓴다.
fclose() 파일을 닫는다.
remove() 파일을 삭제한다.
rename() 파일 이름을 바꾼다.
rewind() 파일 위치를 초기화한다.
tmpfile() 임시 파일을 만들고 연다. fclose()로 닫으면 임시 파일이 삭제된다.
clearerr() end-of-file와 주어진 스트림에 대한 오류 지시자를 지운다.
feof() end-of-file 지시자가 주어진 스트림으로 설정되어 있는지 검사한다.
ferror() 오류 지시자가 주어진 스트림으로 설정되어 있는지 검사한다.
fflush() 보류 중인 버퍼된 출력을 주어진 스트림의 파일에 강제로 쓴다.
fgetpos() 첫 번째 변수 (FILE *) 부터 두 번째 변수 (fpos_t *)의 파일 위치 지시자를 저장한다.
fgetc() 파일로부터 한 개의 문자를 리턴한다.
fgets() 파일로부터 문자열을 읽는다. (파일의 끝이거나 개행 문자의 끝)
fputc() 한 문자를 파일에 입력한다.
fseek() 파일을 찾는다.
fsetpos() 기억된 첫 번째 인수(FILE *) 두 번째 인수(fpos_t *) 까지의 파일 위치 지시자를 설정한다.
fread() 파일로부터 데이터를 읽어들인다.
fwrite() 파일로부터 데이터를 쓴다.
getc() 주어진 스트림으로부터 문자를 읽고 리턴한다. 강화된 파일 지시자로서, 주어진 스트림을 한 번 이상으로 평가하는 fgetc와 같은 효과를 내는 매크로이다.
ungetc() 문자를 스트림의 역순으로 읽는다.
getchar() getc(stdin)와 같은 효과를 냅니다.
gets() stdin이 개행문자를 발생시키고 인수에 저장할 때까지 문자를 읽는다.
putc() 스트림에 문자를 쓴다.
putchar(), fputchar() putc(stdout)와 같은 효과를 낸다.
puts() stdout에 문자, 문자열을 출력한다.
printf, vprintf() 표준 출력 스트림에 출력한다.
fprintf(), vfprintf() 파일로 출력한다.
sprintf(), snprintf(), vsprintf(), vsnprintf() 문자 배열로 출력한다. (C 문자열)
scanf(), vscanf() 표준 입력 스트림으로 입력한다.
fscanf(), vfscanf() 파일로 입력한다.
sscanf(), vsscanf() 문자 배열로부터 입력한다. (예: C 문자열)
setbuf(), setvbuf() 주어진 스트림에 버퍼링 모드로 전환한다.
perror() stderr에 오류 메시지를 쓴다.
tmpnam() 임시 파일을 만든다.


※ stdio.h 헤더 파일 멤버 상수 및 변수


상수/변수 명 내용
EOF end-of-file 절을 가리키는 용도로 사용되는 int형의 음의 정수.
BUFSIZ setbuf() 함수에 의해 버퍼 크기를 나타내는 정수.
FILENAME_MAX 충분히 열 수 있는 저장 가능한 파일 이름의 char형의 배열 크기.
FOPEN_MAX 동시에 열 수 있는 파일의 갯수. (최소 8)
_IOFBF “input/output fully buffered”의 약어. setvbuf() 함수에 넘겨서 버퍼화된 블록의 스트림을 열기 위해 입출력에 요구한다.
_IOLBF “input/output line buffered”의 약어. setvbuf() 함수에 넘겨서 버퍼화된 라인의 스트림을 열기 위해 입출력에 요구한다.
_IONBF “input/output not buffered”의 약어. setvbuf() 함수에 넘겨서 버퍼화 되지 않은 것으로 스트림을 열기 위해 입출력에 요구한다.
L_tmpnam char 배열이 tmpnam() 함수를 발생시킬 정도의 충분한 크기.
NULL 널 포인터의 약어인 매크로 상수. 메모리의 어떤 유효한 위치의 개체도 가리키지 않는 포인터 값이다.
SEEK_CUR fseek() 함수의 요구한 현재 파일 위치의 상대 위치를 나타내는 정수.
SEEK_END fseek() 함수의 요구한 end of file의 상대 위치를 나타내는 정수.
SEEK_SET fseek() 함수의 요구한 파일의 시작점의 상대 위치를 나타내는 정수.
TMP_MAX tmpnam() 함수가 생성가능한 최대 파일명 길이. (최소 25자)
stdin 표준 입력 스트림(일반적으로 키보드)를 참조하는 FILE에 대한 포인터.
stdout 표준 출력 스트림(일반적으로 디스플레이 터미널)을 참조하는 FILE에 대한 포인터.
stderr 표준 오류 스트림(항상 디스플레이 터미널)을 참조하는 FILE에 대한 포인터.


하앍... 제 전공이자 전문이자 직업인 C언어가 나오니 흥분했어여... 야미야미 >~ <

요즘은 "탈잉" 이나 "크몽" 이라는 외주업체 혹은 강의/과외를 할 수도 있군녀! 이건 법으로 안걸리나 모르겠지만여!! 이렇게 신기하게 신청할 수도 있네여!!! 와와 대박 신기... 거의 원시인 수준...



헿헤헿ㅎ 다시 본론으로 돌아가면, opendir(), readdir(), rewinddir(), closedir() 함수는 위 stdio.h 헤더파일에 없잖아여!? 이 함수들은 멋찐 갓승훈 선생님께서 POSIX 표준 함수를 이용하신 거랍니다!!


POSIX

※ POSIX 표준 함수


헤더파일 명 내용
cpio.h 특별한 숫자의 cpio 아카이브 형식임.
dirent.h 디렉터리의 개방과 목록 확인을 허용함.
fcntl.h 파일을 열고, 잠금 및 다른 작업을 할 수 있음.
grp.h 사용자 그룹 정보를 제어함.
pthread.h POSIX 스레드를 생성하고 조작하기 위한 API를 정의함.
pwd.h 패스워드 (사용자 정보)를 접근하고 제어할 수 있음.
sys/ipc.h 프로세스 간 통신 IPC.
sys/msg.h POSIX 메시지 큐.
sys/sem.h POSIX 세마포어.
sys/stat.h 파일 정보 (통계분석) 등.
sys/time.h 시간과 날짜 기능과 구조.
sys/types.h 어떤 곳에서든지 사용되는 다양한 데이터 유형.
sys/utsname.h uname 에 관련된 구조들.
sys/wait.h 종료된 자식 프로세스의 상태 (대기 참조).
tar.h 압축(tar)된 아카이브 형식의 특별한 숫자.
termios.h 터미널 입출력(I/O) 인트페이스를 허용함.
unistd.h 다양한 필수 POSIX 함수와 상수.
utime.h 아이노드(inode) 접근과 수정시간.
등…


세상에 마상에.. 뭔놈의 헤더파일과 함수가 이렇게 많은지... C언어를 할 수는 있을지... 너무나 걱정이시라구여!? 걱정마세여!! 우리에겐 구글링이 있잖아여!! 헿헤 어떻게 사람이 한 방면으로 천재가 되겠어여.. 다 공부하고 파고드는 수밖에 없져!! 그러니 초조해 하지 말아여~!!


ANSI C 표준 라이브러리는 POSIX C 표준 라이브러리에 다 포함되어 있어서 결론적으로 우리가 사용하는 표준 라이브러리는 POSIX 구나!! 그런데 ANSI 는 또 무엇이며 POSIX 는 또 무엇인가!!


ANSI vs POSIX

ANSI(American National Standards Institute, 미국 국립 표준 협회)는 ISO(International Organization for Standardization, 국제 표준화 기구) 및 IEC(International Electro-technical Commission, 세계전자기술 위원회)의 일원이며, ASCII 를 제정한 협회입니다!! 아스키코드!! 더 자세한 것은 외쳐 위키백갓!!(출처 : https://en.wikipedia.org/wiki/American_National_Standards_Institute)

POSIX(Portable Operating System Interface, 이식 가능 운영체제 인터페이스)는 서로 다른 UNIX OS의 공통 API를 정리하여 이식성이 높은 유닉스 응용 프로그램을 개발하기 위한 목적으로 IEEE가 책정한 애플리케이션 인터페이스 규격이예요. X는 갑자기 튀어나왔져!? Unix, Linux를 *nix 라고 부르는 시대에, X로 끝나는 공통성을 따서 POSI ~ X 로 부르게 되었다고 합니당!!(출처 : https://en.wikipedia.org/wiki/POSIX)


오늘 우리가 이 함수를 이용해서 무엇을 하느냐구여!? 여러분 리눅스 혹은 윈도우 프롬프트를 이용하시면 dir 명령을 아시나여!? 이 명령이 위 POSIX C 표준 라이브러리를 이용해 만들 수 있는 명령어예여!! 우리가 리눅스의 커맨드를 만든다구여!!

또한 fopen(), fread(), fwrite(), fseek() 을 이용하면 cat 명령어도 만들 수 있으니!! 호모나 섹상에!!


이제 다시 책으로 가면... 왠지 불길함이 엄습하며 야미가 또 초반에 서론으로 힘 다빼고 이제 끝내려나보다~ 싶었더니 제가 설명 드린 줄 알았던 Union(공용체)이 나오네요!!


Union vs Struct

Union과 Structure의 차이점이 많이 헷갈리실 거예요!
Union(공용체)이란, Shared Memory 형태로 가장 큰 byte 크기의 자료형을 기준으로 메모리를 사용하는 것인데요, 100번의 말보다 그림과 함께 직접 실습해보는 것이 가장 와닿는 것 같아요!!



위와 같은 공용체가 선언되어 있다면, 과연 이 공용체의 크기는 몇 byte 일까요!?

가장 큰 byte 크기의 자료형을 기준으로 메모리를 사용한다고 했으니 4bytes 가 아닐까여!? 정답입니다!! 꺄를~~



공용체는 이렇게 같은 위치를 공유해요!! 구조체와는 다르지만 구조체를 여기서 같이 비교하면 복잡하실 수 있으니 아래에서 구조체를 따로 설명 드릴게요!!

그렇다면 저 위의 공용체 선언부를 그림으로 표현하면 다음과 같겠죠!?



과연 그럴까여!? 땡!! 이예요!! 이렇게 쓰이면 거의 pragma pack(push, 1)과 같은 느낌이네여... 이렇게 까지 효율적이진 못해요 ㅜㅠㅜ



바로 이렇답니다!! 뭔가 생김새가 이상하져? 이 생김새를 보면 약간 의심스러운 부분이 생기지 않나여?! 혹시나 같은 주소를 사용하여 이녀석이 다른 변수에 침범하진 않을지...


그러면 바로 실전으로 들어가시면 됩니다!! 저희는 주춤주춤 할 시간이 어없서어여어~!! 랜덤게임~랜덤게임~ ㅋㅋㅋ이거 하니깐 오상진이 프리한 19 라는 예능 방송에서 술자리게임 했던거 기억나네요!! 네이버에 "프리한 19 술자리게임" 검색하시면 나와여!!! 저작권법때문에 올려드릴 쑤가 없네용 ㅜㅜ

이거 새벽에 보다가 웃겨가지구 ㅜㅠ 나중에 해보고 싶었지만... 이미 술게임 하기에는 나이가 있어서.... 안하기루...헿


그럼 위와 같은 공용체를 실제로 사용하면 침범할지 안할지 알아볼까여!!?



빠밤... 우려한대로 이녀석이 침범해버렸어여... 공용체도 잘못 사용하면 변수가 뒤죽박죽 되어서 문제를 일으킬 수도 있다는 점!! 구조체는 그럴 일은 없지만 메모리를 많이 잡아먹고... 어떤 것을 사용해야 할 지 참 난~감하죠잉!?


그렇다면 구조체란!? 각 변수에 따라 각자 할당해 주며, 기본 자료형은 구조체 내부 멤버 중 가장 큰 자료형을 따르게 되어있어요. 만약 int num; char a; 가 있다면, 4bytes 인 int 자료형과 1byte 인 char 자료형이지만 가장 큰 자료형인 int 형을 따라서 구조체의 크기는 8bytes가 되지요. 8bytes 중 5bytes 만 사용하고 나머지 3bytes는 비어있는 겁니다! 넘나 비효율적이지요!?

그래도 위 공용체처럼 주소값이 공유되어 값이 수정되는 일은 없으니 효율적일 수도 있겠구요... 넘나 복잡하지여!?



바로 이런 식으로 되는 것이죠!! 그렇다면 실전을 통해 보실까여!?



비교를 위해 char d; 구조체 멤버 변수 하나를 뺐어요! 왜냐하면 그게 있으면 8bytes가 딱 맞아 보이니까요!!

현재 구조체는 7bytes 이지만 구조체 크기로는 8bytes가 나오는 것을 확인하실 수 있지요!?

또한 union과 다르게 각 변수가 각자의 값을 가지고 있다는 것을 알 수 있어요!! 결국 각자의 주솟값을 가지고 있다는 것이지요!!


넘나 신기한 C언어의 세계~~ 매력에 푹 빠지시지 않나여? 헿...아니라구여...? 왜여..!! 빼액!!!


이제 책을 다시 보시면 갓승훈 선생님께서 각 함수를 어떻게 구현하는지, 어떠한 핸들을 이용하고 이 핸들은 풀로 형성해서 어떻게 함수를 사용하는지 너무도 자세하게 알려주실 거예요!! 이 FILE I/O 를 이용해서 나중엔 ASCII ART도 열 수 있답니다!! 제가 다음에 동영상으로 보여드릴게여!! 헿...


오랜만에 찾아온 야미인데 홍보만 하다가 가는건 아닌지 모르겠네영 ㅜㅠㅜ 그래도 이제 얼마 남지 않은 시간인데 인원이 너무도 없어서여... 이러다 과외될둡...히익

최대한 자주 올게여!! 평소에 아침 7시에 기상해서 1시간 30분간 버스를 타서 오전 10시까지 출근하고, 열씸히 월급루팡하지 않고 일만해서 최소 오후 10시, 최대 새벽 4시까지 개발을 하는 개발자 인생이기에.. 자주 못 찾아오더라도 양해를... 쿨럭...


그럼 다음에 뵈어요!! 뿅!!


Check out the yummyhit’s website for more info on who am i. If you have questions, you can ask them on E-mail.

카테고리:

업데이트:

댓글남기기