1) 지식 창고는 본인이 작성한 콘텐츠(팁/노하우/리소스/강좌 등)을 무료 혹은 가상화폐인 납포인트를 통해 공유하는 공간입니다.
2) 본인이 작성한 콘텐츠에 대해서만 지식 창고에 등록할 수 있으며, 저작권에 위배되는 콘텐츠는 사전경고 없이 삭제될 수 있습니다.
3) 콘텐츠 구매 및 첨부파일 다운로드는 회원그룹 '연구원' 이상 가능하오니, 경험치를 쌓아 진급한 후에 이용 부탁드립니다.
4) 무료 콘텐츠의 본문은 구매절차 없이 즉시 이용할 수 있으며, 판매 납포인트가 있는 콘텐츠는 구매 후 이용할 수 있습니다.
5) 콘텐츠 판매에 따른 납포인트 수익은 지정한 비율(50%)에 따라 판매자에게 지급하며, 납포인트 수익을 통해 진급을 빨리할 수 있습니다.
6) 구매 후 평가를 하면 구매 납포인트의 20%를 돌려 드립니다.
판매자 | 프리미엄 | 판매 납포인트 | 무료 | 평점 | 0점 / 총 0명 참여 |
---|
***************************< 캠퍼스 C 강좌 >******************************
[제목] :
[코드] : campusc1-027 (초급)
[교재] : CAMPUS C (초급, Third edition) [출판사 : 책과스승]
[알림] :이 파일은 "캠퍼스 C"에서 모든 분께 공개한 "초급 강좌"입니다.
이 [알림]의 내용을 지우지 않는다면 누구에게나 임의로 복사해 줄 수
있습니다. 그러나 이 강좌 내용에 대한 저작권은 "캠퍼스 C"에 있습니다.
[연락처] : 605-8662 (서울) ("캠퍼스 C", 도서출판 "책과 스승")
천리안 : go campusc
나우콤 : go lcampc
하이텔 ID : campusc
****************************<< 목 차 >>************************************
<1> 프리 프로세서(preprocessor) 란...
<2> #include xxx.h 에 관하여
<3> #define 에 관하여
***********************************************************************
<1> 프리 프로세서(preprocessor) 란...
***********************************************************************
C 에는 프리 프로세서라는 것이 있다. 이것은 영어 뜻 그대로 "미리
(앞서서) 처리하는 것"" 이라는 뜻인데, 여기서는 "컴파일 하는 것 보다" 라
는 말이 생략된 것이다. 즉 다시 써 보면 "컴파일을 하는 것 보다 미리(앞서
서) 처리하는 것" 이라는 뜻이다. 이 과정에 대한 개요도가 [288쪽]에 있는 그
림이다.
이 프리 프로세서의 종류는 몇 가지 안된다. 그나마 이중에서 가장
많이 쓰이는 것들은 이미 우리가 알고 있다. 그것들은 전부 앞에 "#"으로 시
작되는 단어들이다. 직접 살펴보면,
#include <stdio.h> <-- 요기 1
#include "my.h" <-- 요기 2
#define PI 3.14 <-- 요기 3
main()
{
}
이것들은 "pre" 라는 의미처럼, 위치도 프로그램의 제일 처음에 나
타난다. 이것들이 하는 일은 우리가 이미 알고 있다. 그리고 그 외의 것은
더 이상은 공부해 봐야 지금 단계에서는 "시험 공부용" 밖에 안될 것이고,
이것들이 처리되는 간단한 내막은 이렇다.
***********************************************************************
<2> #include xxx.h 에 관하여
***********************************************************************
#include <stdio.h>
프로그램에서 위의 의미는 말 그대로 stdio.h 라는 헤더 파일을 "포함
(include)해라"는 뜻이다. 따라서 실제로 stdio.h 라는 파일을 통째로 가져
와서 이 자리에 넣어 둔다. 예를 들어 우리가 다음과 같은 프로그램을 짰다
고 치자. 딱 4줄이다.
#include <bios.h>
main()
{
}
그러나 이걸 컴파일 시키려고 [CTRL + F9] 키를 누르면, 컴파일러에 들어가
기 직전에 stdio.h를 이 자리에 불러오기 때문에 다음과 같이 변한다.
/*---------------< 진짜 bios.h 파일 시작>---------*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
int _Cdecl bioscom(int cmd, char abyte, int port);
int _Cdecl biosdisk(int cmd, int drive, int head, int track, int
sector,
int nsects, void *buffer);
int _Cdecl biosequip(void);
int _Cdecl bioskey(int cmd);
int _Cdecl biosmemory(void);
int _Cdecl biosprint(int cmd, int abyte, int port);
long _Cdecl biostime(int cmd, long newtime);
/*-------------------< 진짜 bios.h 파일 끝>----------------*/
main()
{
}
이와 같이 "통째"로 들어다가 이 자리에 놓기 때문에 우리가 비록 4
줄 짜리 소스 프로그램을 짰더라도 소스 파일의 크기는 엄청나게 커지는 것
이다.
그렇다고 우리가 걱정할 필요는 없고 컴파일러가 조금 바빠지는 것
뿐이다. 그러면 다음과 같은 프로그램을 보면 어떤가 ? 여러분의 시각이 조
금 달라졌는지 모르겠다.
#include <bios.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
main()
{
}
이 강좌의 첫 부분에서도 얘기한 적이 있는데, 우리가 비록 4줄 짜
리 프로그램을 짜서 xxx.c 라고 만들었다고 해도, 컴파일을 하고 나면,
xxx.obj 와 xxx.exe 파일이 커지는 것을 안다. 그 이유 중의 하나가 위와
같은 #include 때문이다. (그리고 또다른 결정적 이유는 "라이브러리 "를
link 시키기 때문이다)
이런 표현도 있다.
#include "bios.h"
main()
{
}
즉 <bios.h> 대신에 "bios.h" 라고 쌍 따옴표를 쓰는 것인데, 의미의 차이
는 다음과 같다.
--------------------------------------------------------------
#include <bios.h> --> 1."지정된 디렉토리"에서만 찾음
#include "bios.h" --> 1."working 디렉토리" 먼저 찾음
2. "지정된 디렉토리"에서 찾음
(못 찾았을 경우에)
--------------------------------------------------------------
항상 말로 표현하려면 더 어려운 것 같은데 용어를 좀 더 자세히 살펴보면
다음과 같다.
-------------------------------------------------------------------
지정된 디렉토리란 --> [Options] [Directories] 의 "include 디렉토리"
working 디렉토리란 --> [File] [Change dir] 에 나타나는 디렉토리
-------------------------------------------------------------------
일단 실제로 위의 디렉토리를 터보 C 메뉴에서 보고 오도록 하자.
"지정된 디렉토리" 를 설명하면 다음과 같다. 보통의 경우 컴파일러
를 깔아 놓으면 디렉토리 구성이 다음과 같다.
c:\tc> ---> 컴파일러가 있는 디렉토리
c:\tc\include> ---> 헤더 파일이 있는 디렉토리 <-- (요기)
c:\tc\lib> ---> 라이브러리 파일이 있는 디렉토리
이중에서 위에 표시한 (요기) 가 "지정된 디렉토리"를 의미한다. 이
디렉토리 명은 위에 적은 대로 [Options] [Directories] 의 "include 디렉토
리" 란에 똑같이 적혀 있을 것이다.
"working 디렉토리"란 자기가 터보 씨를 부르기 전에 최후에 있었던
디렉토리를 의미한다. 즉 자기 시스템에 path 가 설정되 있으면 아래와 같이
아무 곳에서나 터보 씨를 부를 수 있다.
c:\tc> tc <-- O.K
c:> tc <-- O.K
c:\hwp20> tc <-- O.K
이런 경우 터보 씨 안에서 [File] [Change dir] 를 가보면 위에 밑줄 친 부
분의 디렉토리 이름이 각각 그대로 나타나는데, 이것이 "working 디렉토리"
이다. 즉 다시 말해서 터보 씨가 현재 어느 디렉토리 위에서 "working" 하고
있는 가를 의미하는 것이다.
이와 같은 용어의 이해를 가지고, 이제 다음과 같은 간단한 예를 들
어보자. 이제부터 하는 것은 다름이 아니고 "이름만 똑같은 파일 my.h를 두
개 만들고 서로 다른 디렉토리에 저장을 해 두자는 것이다." 그리고 나서 우
리가 짠 C 프로그램 안에서 #include <my.h>를 사용했을 경우와 #include
<my.h>를 사용했을 경우의 차이를 알아보는 것이다.
"my.h" 란 이름으로 파일을 하나 만들어 보자. 그리고 아래와 같이 저장을
하자.
1. my.h 라는 파일을 하나 만들자. 이 파일은 텍스트 파일이어야 하므로, 아
래 한글로 만들경우 "아스키 타입"으로 저장하기로 한자. 내용은 아
래와 같이 한줄만 포함한다.
#define MAX 100
2. c:\xxx> 밑에 my.h를 넣어 두자 ( 아무 디렉토리에 넣으라는 뜻임)
3. 이제 역시 똑같은 이름 "my.h"로 다른 헤더 파일을 만들자. 이것도 역시
텍스트 파일이어야 한다. 그리고 이번에는 아래와 같이 값이 123 이다.
#define MAX 123
4. 이제 c:\tc\include> 밑에 my.h를 넣어 두자.
(자기 시스템의 "헤더 파일"들 있는 곳에 저장하라는 뜻임)
그리고 프로그램을 다음과 같이 짜 보자.
#include <my.h> <-- (요기)
main()
{
printf("max = %d", MAX);
}
이 프로그램은 아주 간단하게도 MAX를 찍어 보라는 것인데, 위에서 (요기)
my.h를 include 한 것을 보라. 우리는 my.h 라는 파일을 두 개 만들었기 때
문에 내가 문제를 낼 수 있다.
<문> 위의 결과는 100 인가 ? 아니면 123 인가 ?
<답> 이 문제의 해답이 저 위에 있다. 올라가기 귀찮으니까 다시 써 보면
--------------------------------------------------------------
#include <xxx.h> --> 1."지정된 디렉토리"에서만 찾음
#include "xxx.h" --> 1."working 디렉토리" 먼저 찾음
2. "지정된 디렉토리"에서 찾음
(못 찾았을 경우에)
--------------------------------------------------------------
위 프로그램은 간단하게도 <xxx.h> 이기 때문에 고민할 것이 아무것도 없다.
즉 "지정된 디렉토리" 에 있는, 다시 말해서 다른 헤더 파일들이 많이 있는
곳에 있는 my.h 의 값이다. 즉 123 을 찍을 것이다.
이 경우는 "working 디렉토리" 와는 아무 상관없기 때문에 답을 간단히 찾을
수 있다. 여태 까지 우리는 이와 같은 이유로, 간단하게 <xxx.h> 타입을 써
왔다.
그러나 실제로 시스템을 개발하거나, 아니면 제법 C 에 자신이 붙기
시작하면, 이른바 시스템을, 자기 맘대로 "주물러 보고 싶을 것"이다. 예를
들어 다음은 "STDIO.H" 에 있는 한 부분이다.
/* Number of files that can be open simultaneously */
#define OPEN_MAX 20 /* Total of 20 open files */
이 부분은 우리가 다음 시간부터 해볼 file에 관한 여러 가지 define들이 있
는 곳인데, 위의 의미는 "동시에 열 수 있는 파일의 갯수" 가 20 개라는 의
미이다. 이건 이른바 default 값이고 임의로 고칠 수도 있는 값이다.
그런데 자기가 이 값을 30 으로 고치고 싶다고 해서 진짜 stdio.h에
가서 30 이라고 써 놓으면, 그것도 일단 욕을 먹을 짓이다. 짐작을 하시겠지
만, 이 stdio.h는 이른바 "원본" 이니까 함부로 손을 대면 곤란한 것이다.
이럴 때는 자기가 똑같은 이름으로 하나 복사해다가 30으로 바꿔 쓰면 문제
는 간단하다. 그리고 역시 아시다시피 똑같은 이름의 파일이 같은 디렉토리
안에 있을 수는 없으므로, 다른 디렉토리에 넣어야 한다.
앞으로 자기가 고친 파일로 컴파일을 할 때는 "원본 대신 자기가 새
로 만든 stdio.h"를 포함하면 되는 것이다. 그런 방법이 아래와 같이 쌍따옴
표로 "stdio.h"를 쓰는 것이다.
#include "stdio.h"
main()
{
printf("%d", OPEN_MAX);
}
<문제> 이제 이 사람이 c:\my_work 디렉토리 밑에 새로운 stdio.h를 복사해
놓고 이걸 쓰고 싶다면, 이 사람은 어디서 터보 씨를 불러야 하는가
? 즉 working 디렉토리는 어디가 되야 하는가 ?
<문제> 만일 이 사람이 "자기가 만든 stdio.h" 가 있는 곳 이 아닌 곳에서
터보 C를 부르면 값은 20 으로 들어가겠는가 ? 30 으로 들어 가겠
는가 ?
말씀 드린대로 이런 작업은 조금 전문적인 실험을 할 때 사용되는 방법이다.
빨리 이런 작업들을 하시길 바라겠다.
***********************************************************************
<3> #define 에 관하여
***********************************************************************
이것도 우리가 너무나 잘 아는 것이다. 우리가 보통 써 왔던 방법은
제일 간단한 아래와 같은 형태 였다.
#define PI 3.14
이것도 역시 프리 프로세서이기 때문에 컴파일 되기 직전에 어떻게
바뀌는지 알아볼 필요가 있다. 다음의 두 파일을 비교하자.
------<원래 소스 파일>------
#define P printf
main()
{
P(" Good ");
P(" morning ");
}
------<컴파일 되기 직전의 파일>------
#define P printf
main()
{
printf(" Good ");
printf(" morning ");
}
-------------------------------------
위의 기능은 그다지 설명이 필요 없을 것 같다. 이것은 단순한 "매
크로" 기능이다. "매크로" 기능에 대해서는 공개 강좌에서 얘기한 적이 있는
데, "긴 문장"을 "짧게" 줄여 쓰는 것을 의미한다.
그러나 이것도 위에서 보다시피, 컴파일 하기 직전에는 원래 형태대
로 바뀌고 컴파일이 된다. 이 바뀌는 과정은 역시 컴파일러의 일이니까 우
리는 신경을 안 써도 된다.
그리고 #define은 이미 정의된 것도 받아서 다시 정의를 할 수도 있
는데 아래는 다 옳은 표현이다,
#define ONE 1
#define TWO ONE + 1
#define THREE TWO + 1
여기서 한 가지 알아야 할 것은, 이 매크로 기능은 지능이 전혀 없
기 때문에, 지능 있는 인간이 신경을 써야 할 경우가 가끔 있다.즉 아래와
같은 경우 조심해야 한다.
#define ONE 1
#define TWO ONE + 1
#define THREE TWO + 1
main()
{
p = THREE * 2;
}
<문제> p는 6인가 ?
위의 정의를 따라서 다시 써 보면 밑줄친 부분이 되는데,
main()
{
p = TWO + 1 * 2;
}
<문제> p는 6인가 ?
뜻하지 않은 오류가 발생 할 수가 있다. 따라서 위와 같이 "여러 단
어"로 구성된 정의는 괄호 ( )를 사용하는 것이 좋다.
#define ONE 1
#define TWO (ONE + 1)
#define THREE (TWO + 1)
매크로에서의 ( )의 의미는 그 지긋지긋한 "우선 순위"의 괄호가 아
니고, 무조건 보이는 글자대로 정의되는 것일 뿐이다.즉
THREE * 2 ---> (TWO + 1) * 2
를 무조건 쓰라는 얘기일 뿐이다. 그러나 결과적으로는 우선 순위의 그것이
되고 말았다.
또다른 #define의 기능은 parameter를 넘기는 것도 있다. 아래를 보
자.
#define ADD(a,b) ( (a) + (b) )
main()
{
int a = 10;
int b = 20;
ADD(a,b);
}
이건 마치 함수의 형태를 쓰고 있고, 게다가 매개 변수 까지 이용하
고 있다. 여기에서는 매개 변수 a, b 에 괄호() 를 쓴걸 유심히 봐야 한다.
이제는 대문자를 쓴걸 보면 매크로라는 것을 금방 아실 것이다. 이
것도 역시 소문자로 써도 상관없다. 그러나 개인적으로 만들어 쓸 때는 "꼭"
대문자를 쓸 것을 권한다. 그래야 누가 이 소스를 읽든지 간에 쉽게 구별을
할 수있다.
위의 프로그램은 우리에게 익숙한 함수 표현법으로 쓸 수도 있다.
즉
main()
{
int a = 10;
int b = 20;
add(a,b);
}
add(int a, int b)
{
return( a + b);
}
이것은 위에 선언한 매크로와 기능이 똑같다. 그러나 여기서 한가지 중요한
비교를 하자. 이것들이 이른바
--------------------------
1. 함수를 이용한 호출
2. 매크로를 이용한 호출
--------------------------
이라는 것이다.
오늘 강좌에서 다룬 내용은 사실 중요해서 했다기 보다, 다른 책에
서는 꼭 쓰길래 나도 구색을 맞추느라고 쓴 것이다. 하지만 지금 하려는 이
내용은 정말 중요한 의미가 있다. 여러분들의 생각은 어떤지 모르겠지만, 프
로그램에 관한 나의 개인적인 생각은 다분히 "실용적인" 면에 치중되 있다.
어떤 사람들은 별로 쓰지도 않는 이상한 부분을 혼자 공부하고, 남보다 더
많이 안다고 자위하는 사람도 있는 것 같은데, 나는 사실 시시콜콜한 부분까
지 아는 것은 많지 않다. 그러나 나의 생각은 오로지 "어떻게 하면"
--------------------------------------------
1. 프로그램을 작고(쓸데없이 길게 하지 않고)
2. 빨리 돌게 만들 수 있는가
--------------------------------------------
하는데 치중되 있다.
이 부분에 관한 한, 나 스스로 느끼기에, 거의 정신병 중기쯤 되지
않았나 싶을 정도의 집착 증세를 보이는데, 이건 비단 나만의 일이 아니다.
아마 프로그램을 전공하거나, 혹은 이 분야에서 일을 하는 사람들은 거의 누
구나 이런 정신병 증세를 보일 것이다.
요즘은 "프로그램의 크기"에 대한 문제는 예전보다 덜하다는 얘기를
한 적이 있는 것 같다. 그러나 "속도" 에 관한 한, 지구상에서 컴퓨터가 사
라지기 전까지는 어림없는 일 일것이다.
이런 관점에서, 위의 두 문제를 비교하려는 것인데, 아래에 결과부
터 적어 보자.
------------------------------------------------------------
함수 호출 매크로 호출
------------------------------------------------------------
속도 : 느리다 빠르다
크기 : 커지지 않는다 커진다.
------------------------------------------------------------
앞으로도 여러분은 더 많은 함수를 사용하게 될텐데, 이 시점부터는
"함수의 호출" 이라는 것이 어떤 의미를 갖는지 개념을 확실히 할 필요가 있
다. 이것은 여러분들이 이미 알고 있을 지도 모르는 내용이지만 여기에서 다
시 한번 그 의미를 의식해 보고자 정리를 해본다.
먼저, 크기의 문제를 보면, 매크로를 자꾸 호출하면 프로그램이 커
진다는 것은 오늘 얘기했으니 알 것이다. 나중에 여러분이 "매크로 어셈블
러"를 공부해 보면 그 개념을 더 명확히 느낄 수 있을 것이다. 그러나 지금
은 간단히 예를 보고 넘어가자. 이건 #include 에서 파일이 커지는 것과 똑
같은 개념이다.
#define HULK "I AM VERY VERY ANGRY !!!"
main()
{
printf(HULK);
}
이것은 컴파일 되기 직전에 다음과 같이 바뀌는 것을 알 것이다.(밑줄 부분)
main()
{
printf("I AM VERY VERY ANGRY !!!");
}
따라서 다음과 같이 프로그램을 짜면
#define HULK "I AM VERY VERY ANGRY !!!"
main()
{
printf(HULK);
printf(HULK);
printf(HULK);
printf(HULK);
printf(HULK);
printf(HULK);
}
데이타가 "뿌지직" 하면서 늘어 나는 게 보일 것이다.
이와 같이 데이타 "자체"의 크기가 자꾸 반복 되서 늘어 나는 것이
기 때문에, 매크로를 부를수록 프로그램의 크기는 자꾸 커진다.(컴파일 되
기 직전에)
이에 비해, 함수를 부르면 번지수만 찾아가서 데이타를 읽어 오는
것이기 때문에 함수가 있는 곳은 항상 일정하고, 아래의 경우, 크기는
hulk()라는 문장만큼만 늘어 나는 것이지, 그 외는 데이타가 늘어날 것이 없
다.
main()
{
hulk();
hulk(); <-- 오로지 늘어나는 부분
hulk(); <-- 오로지 늘어나는 부분
hulk(); <-- 오로지 늘어나는 부분
hulk(); <-- 오로지 늘어나는 부분
}
hulk()
{
printf("I AM VERY VERY ANGRY !!!");
}
함수를 부를 때의 과정은, 이른바 "context"를 바꾸는 일을 하는 것
이다. 이런 자세한 내용은 중급 강좌쯤 되면 자세하게 얘기를 할 수 있을 것
같고, 어셈블러와 C를 link 시킬 때 필수적으로 공부를 해야 하는 부분이다.
여기서는 간단하게 얘기해 보면, 지난 시간에 CPU의 레지스터를 살
펴 본 적이 있는데, 프로그램이 진행되고 있는 동안은 이 레지스터들이 거의
전부 동원되서 하나의 일을 착착 진행하고 있다. 그런데 갑자기 함수를 부르
면 여태까지 하던 일을 잠시 접어 두고, 레지스터에 있는 값들도 전부 저장
해 두고 새로운 환경에서 일을 시작하는 것이다. 이런 경우와 비슷하다.
예를 들면 지금 오케스트라 단원들이 베토벤의 교향곡 "운명"을 심
각하게 연주를 하고 있다. 그런데 갑자기 상부에서 "산토끼"를 연주하라고
지시가 왔다. 그러면 단원들이 전부 와당탕거리며 악보를 바꾸고, 산토끼 분
위기에 맞게 감정 조절도 하고, 지휘자에 맞춰 "산토끼 토끼야" 를 시작해야
한다.
이런게 이른바 context 변환(switch) 이다. 산토끼가 다 끝나면, 아
까 하던 "운명"을 계속해야 하니까, 다시 context를 바꾼다. 단원들이 또 와
당탕거리며 악보를 바꾸고 정신을 가다듬고 심각하게 연주를 계속한다.
이걸 C로 표현하면 아래와 같다.
main()
{
unmyung(); /* "배 도변"의 운명 */
}
/*----------*/
unmyung()
{
san_to_gi();
}
/*----------*/
san_to_gi()
{
}
이런 과정을 거치기 때문에 함수를 자꾸 부를수록 크기는 늘어나지
않으나, context를 바꾸는데 시간이 자꾸 걸리게 된다. 물론 이 시간이라는
건 그야 말로 미미하지만, 함수를 사용하지 않으면 이 시간마저도 절약할 수
가 있는 것이다.
게다가 다음과 같은 경우라면, 우리 정신병자들은 또 입에서 욕이 나올지도
모른다.
main()
{
int i;
for(i=0; i < 10000; i++) {
hulk();
}
}
hulk()
{
printf("I AM VERY VERY ANGRY !!!");
printf("LONG LONG sentence................");
}
위의 것을 함수를 사용하지 않고 다시 쓰면,
main()
{
int i;
for(i=0; i < 10000; i++) {
printf("I AM VERY VERY ANGRY !!!");
printf("LONG LONG sentence................");
}
}
프로그램도 간결해 졌을 뿐 아니라, 실행 속도도 빨라졌다.
<숙제> 위 두개의 프로그램을, 속도의 개념을 느낄 수 있을 때 까지 반복해
서 읽어보세요.
(이 숙제를 성공적으로 하신 분들은 우리 "정신 그룹"에 동참하신
것을 환영한다.)
<숙제> 아래는 두개 프로그램의 실행 시간 차이를 검사하기 위한 것이다.
실행해 보고 시간 차가 얼마나 나는지 검사하라. 참고로 위의 결
과는 초 단위로 표시하는 것이다.
/*-----------< 프로그램 1 >-----------*/
#include <stdio.h>
#include <time.h>
time_t t_begin, t_end;
main()
{
int i;
time(&t_begin);
for(i=0; i < 1000; i++) {
hulk();
}
time(&t_end);
printf("elapsed time = %f\n", difftime(t_end, t_begin));
}
hulk()
{
printf("I AM VERY VERY ANGRY\n");
}
/*-----------< 프로그램 2 >-----------*/
#include <stdio.h>
#include <time.h>
time_t t_begin, t_end;
main()
{
int i;
time(&t_begin);
for(i=0; i < 1000; i++) {
printf("I AM VERY VERY ANGRY\n");
}
time(&t_end);
printf("elapsed time = %f\n", difftime(t_end, t_begin));
}
위의 결과는 초 단위로는 거의 차이가 없을 것이다. 그러나 앞으로
는 함수를 호출 할 때 매크로를 쓰는 것보다는 더 걸린다는 내막은 이해를
해야 한다. 그리고 속도를 따진다면 당연히 함부로 함수를 호출할 수는 없을
것이다.
지금 우리 같은 개인적인 컴퓨터를 쓸 때는 이런 건 그다지 심각한
문제가 아니지만, 비행기 콘트롤 기능을 담당하는 컴퓨터라든지, 미사일을
제어하는 컴퓨터 등과 같이, "시간"이 중요한 역할을 하는 컴퓨터에서는 심
각한 영향을 끼칠 수도 있다. 예를 들면 이런 것이다.
전쟁 중에 미제 전투기 F-18 따위가 날아가다가 마주 오는 괴비행체
를 발견했다. 이게 적기라면 당장 미사일을 날려 버려야 되는데, 사람은 도
저히 판단을 할 수가 없다. 전투기의 컴퓨터에게 물어본다. "빨리 대답해라
바쁘다 !" 그리고 잠시후, 컴퓨터가 적기라고 알려 주었다면 (어떻게 구별하
는 지는 잘 모르겠지만...) 그 때 부랴부랴 미사일 단추를 눌러야 한다.
물론 상대방의 조종사도 바보가 아닌 다음에야 역시 똑같은 짓을 했
을 것이다. 따라서 만일 적비행기의 컴퓨터 실행 속도가 더 빨랐다면, 이미
적의 미사일은 내 코 앞에 와 있을 것이다.
"쾅 ..."
이 조종사가 프로그램을 좀 안다면 죽어가면서 의심을 할 수도 있을 것이다.
"어떤 x 같은 프로그래머가 느리게 짜서 한 발 늦었구나..."
다시 한번 말하지만, 이런 상황은 정신병적인 차원에서 느낄 수 있
는 것이다, 그리고 지금처럼 특별한 상황의 컴퓨터에서나 그 의미가 있는 것
이다. 따라서 지금 여러분들이 IBM-PC를 가지고 공부하면서 ,만사 제쳐놓고
"빠르게 !"만 외칠 필요는 없다. 그러나 재미없는 문법 공부를 끝내고 나면
누구나 이런 문제에 흥미를 가질 것이 분명하다. (그래서 어셈블러 공부들도
할 것이고)
참고로 이런 처리를 하는 것을 영어로 "Real time processing"이라
고 한다. 우리말로 "실시간 처리" 라고 하는 것 같은데, 개념적으로는 지금
얘기한 바와 같이 "순식간에 재빨리 응답하는 일 처리 방식"쯤 되는 것이다.
여기서 생기는 문제는, 과연 얼마나 빨리 응답해야 "재빨리 응답"하
는 것인가 하는 문제인데, 그런 건 정답이 없는 듯하다. 이를테면 비행기 자
동 조정 장치는 비행기가 중심을 잃고 떨어지기 시작하면 "재빨리" 균형을
잡을 수 있을 정도만 되면 되는 것이고, 핵발전소에서 "연료봉"이 너무 깊숙
이 들어가서 뜨거워지면, "재빨리"(발전소 터지기 전에) 연료 봉을 들어올릴
수 있을 정도로 "신속하게 작동"만 하면 되는 것이다.
이런 것도 아주 흥미 있는 컴퓨터 프로그래밍 분야의 하나임을 알려
둔다.
<숙제> 이 시간 검사 방법으로 "자동변수" 를 썼을 때와 그렇지 않은 경우의
시간차를 역시 순환문을 써서 검사해 보세요.
<숙제> 지난 시간의 그래픽 프로그램을 my.h를 이용하여 다시 만들어 보세
요.
**************************< 끝 마치며 >********************************
수고 하셨습니다.
***********************************************************************
이거 네이버카페에서도 본 듯한데, 같은 글인 것 같군요.
머 여튼 읽을 때마다 좋은 강좌 같아요 ^^