표준 함수

old/C Grammer 2010. 11. 19. 11:05
1. 수학 함수

1) 표준 함수

C컴파일러는 많은 수의 표준 함수들을 제공한다. 공통적으로 자주 사용되는 기능들을 모든 개발자들이 직접 만들어 쓴다면 시간도 많이 걸릴 것이고 사회적인 낭비도 심할 것이다. 모든 개발자들이 화면 입출력을 위해 printf, scanf 같은 함수를 일일이 만들어 써야 한다면 얼마나 끔찍하겠는가? 이런 함수들의 기능은 워낙 뻔하기 때문에 누가 만들어도 비슷한 모양을 가질 것이며 어떤 특수하고도 고유한 기능을 요구하는 것도 아니다.

표준은 필요한 함수의 최소한의 목록만을 규정하며 컴파일러 제작사는 필요에 따라 함수를 더 추가로 정의할 수도 있다. 그래서 컴파일러 제작사에 따라 런타임 라이브러리의 구성이 조금씩 달라질 수 있으므로 약간의 주의를 기울일 필요는 있다. 예를 들어 터보 C에는 gotoxy, clrscr 함수들이 있지만 비주얼 C++에는 이 함수들이 없으며 같은 함수라도 이름이 조금씩 다른 경우도 있다. 하지만 printf, puts, getch 같은 기본적인 함수들은 대부분의 컴파일러에 공통적으로 존재하므로 컴파일러에 상관없이 자유롭게 사용할 수 있다. 표준 함수들은 기능에 따라 다음과 같이 분류할 수 있다.

분류

함수

입출력 함수

printf, scanf, gets, puts, getch, putch

수학 함수

sin, cos, tan, pow, floor, ceil, hypot

문자열 함수

strcpy, strlen, strcat, strstr, strchr

시간 함수

time, asctime, clock

파일 입출력 함수

fopen, fclose, fseek, fread, fwrite

프로그램 제어

exit, abort, system

메모리 할당

malloc, free, realloc, calloc

기타

rand, delay


 2) 삼각 함수

수학 함수는 수학적인 계산을 하는 함수들이다. 수학 함수들의 원형은 모두 math.h에 선언되어 있으므로 이 함수들을 사용하려면 제일 먼저 #include <math.h> 전처리문을 삽입하여 이 헤더 파일을 포함시켜야 한다. 이 책에서 사용하는 Turboc.h가 이 헤더 파일을 포함하고 있지 않으므로 math.h를 포함하지 않으면 수학 함수를 쓸 수 없다. 실제 프로젝트를 할 때도 반드시 math.h를 인클루드해야 함을 꼭 기억해 놓도록 하자.

수학 함수 중에 비교적 이해하기 쉬운 삼각 함수에 대해 먼저 정리해 보자. 삼각 함수들은 이름만 다르고 원형이 모두 동일하다. 실수형 인수를 하나 받아들이며 이 인수의 삼각함수값을 계산하여 그 결과를 실수로 리턴한다.

double sin(double x);
double cos(double x);
double tan(double x);
double asin(double x);
double acos(double x);
double atan(double x);
double sinh(double x);
double cosh(double x);
double tanh(double x); 

기본적인 수학 교육을 받았다면 sin, cos, tan 함수가 어떤 값을 계산한다는 것은 잘 알고 있을 것이다. asin, acos, atan 함수는 기본 삼각 함수의 역함수들이며 sinh, cosh, tanh는 쌍곡선 삼각함수라는 것이다. 설마 그럴리야 없겠지만 삼각 함수가 뭐하는 함수인지 모르겠다는 사람은 수학책을 참고하기 바란다. 이 책은 수학책이 아니므로 함수들이 구하는 값의 수학적 의미에 대한 설명은 하지 않기로 한다.

삼각 함수들이 받아들이는 인수 x는 360분법의 각도가 아니라 호도(라디안)값이다. 1호도는 원주의 길이가 반지름과 같아지는 각도인데 180/3.1416으로 정의되어 있다. 따라서 각도값으로 호도를 구할 때는 다음 공식을 사용하면 된다.

호도=각도*3.1416/180

sin(r*3.1416/180)


3) 지수 함수

지수 함수는 거듭승이나 제곱근, 로그 따위의 값을 구하는 함수들이다. 실수 차원에서 계산을 하므로 취하는 인수나 리턴값은 모두 정밀도가 높은 double 실수형이다. 다음과 같은 것들이 있다.

함수

설명

double sqrt(double x);

x 제곱근

double pow(double x,double y);

xy. x y

double log(double x);

자연 대수

double log10(double x);

상용 대수

double exp(double x);

자연 대수 exp

double hypot(double x,double y);

직삼각형의 사변 길이

 sqrt 함수는 제곱근, 즉 두 번 곱해서 그 값이 되는 수를 구한다. sqrt(4)의 결과는 2.0이 될 것이며 sqrt(2)는 에 해당하는 1.414214를 리턴할 것이다. 어떤 수 x의 제곱을 구할 때는 x를 두 번 곱하는 x*x식을 사용하는데 세제곱 이상을 구할 때는 pow 함수(Power의 약자이다.)를 사용하는 것이 더 편리하다. 예를 들어 2의 10승을 구하고자 한다면 pow(2,10)을 호출하면 된다. 베이직이나 파스칼같은 고급 언어는 거듭승을 구하는 별도의 연산자(^)가 제공되지만 C언어는 거듭승 연산자를 따로 제공하지 않으므로 pow 함수를 사용해야 한다.

log 함수는 로그값을 계산하고 log10은 밑이 10으로 고정되어 있는 상용 로그값을 구한다. 지수 함수 중에는 hypot 함수(Hypotenuse의 약자이다.)가 제일 어려운데 이 함수도 잘 알아두면 유용하게 쓰일 곳이 많다. hypot가 계산하는 값은 인수로 주어진 x와 y의 제곱의 합에 대한 양의 제곱근이다. 무척 복잡한 것 같지만 수식으로 표현해 보면 이다. 이 수식은 직각 삼각형의 빗변 길이를 구하는 공식인데 이른바 피타고라스의 정리라고 한다.

hypot(x,y)는 sqrt(pow(x,2)+pow(y,2))와 동일하며 조금 더 간단하게 쓴다면 sqrt(x*x+y*y)와 같다. 두 점의 좌표를 알고 있을 때 이 두 점간의 거리를 구하고 싶다면 hypot 함수를 사용한다. 예를 들어 한 점을 중심으로 하고 나머지 한 점까지를 반지름으로 하는 원을 그린다거나 할 때 이 함수가 필요할 것이다. 사용예를 보이고 싶으나 콘솔 환경에서는 그래픽을 그릴 수 없으므로 다음에 그래픽을 배우면 그때 직접 실습해 보기 바란다.

요즘은 컴퓨터라는 기계가 게임도 하고 인터넷도 하고 영화도 보고 다양한 용도로 활용되고 있지만 원래 컴퓨터는 수학적인 계산을 위해 만들어진 것이다. 그래서 프로그래밍은 수학과 아주 밀접한 연관이 있는데 간단한 프로그램은 사칙 연산으로도 원하는 대부분의 계산을 할 수 있지만 조금만 복잡해지면 고등 수학이 필요해진다.


4) 정수화 함수

정수화 함수는 실수형 데이터에서 정수부만을 취하는, 즉 소수점 이하의 소수부를 잘라 버리는 함수이다. 소수부를 잘라 버린다고 해서 계산 결과가 정수가 되는 것은 아니며 리턴값은 여전히 실수이다. 실수값의 소수부만을 0으로 만든다고 생각하면 된다. 정수화 함수에는 다음 두 가지가 있다.

double floor( double x );
double ceil( double x );

두 함수는 소수점 이하를 자르는 방식이 다른데 floor는 소수점 이하를 버리고 정수부만을 취하고 ceil은 소수점 이하를 올림해서 정수부를 1증가시킨다. 다음 호출 예를 보면 쉽게 이해가 될 것이다.

floor(3.14);             // 결과는 3.0
ceil(3.14)           // 결과는 4.0

floor는 내림을 하는 함수이고 ceil은 올림을 하는 함수라고 일단 정리할 수 있다. 그러나 단순히 내림, 올림으로 이 두 함수의 동작을 정의하는 것은 정확하지 않다. 다음 예를 보자.

floor(-3.14);       // 결과는 -4.0
ceil(-3.14)              // 결과는 -3.0 

결과가 조금 이상해 보이는데 인수가 음수일 때 floor는 정수부가 1 감소하며 ceil은 소수부를 버린다. 왜 그런가 하면 음수에서도 버림에 의해 수가 더 작아져야 하고 올림에 의해 수가 더 커져야 하기 때문이다. 그래서 floor, ceil 함수의 동작을 좀 더 일반적으로 표현하면 다음과 같다.

floor : 주어진 인수보다 크지 않은 최대 정수
ceil : 주어진 인수보다 작지 않은 최소 정수

수직선상에서 이 함수들의 동작을 설명해 보면 floor는 인수의 바로 왼쪽 정수값을 구하고 ceil은 바로 오른쪽 정수값을 구한다.

수 체계를 시각화해서 보면 좀 더 쉽게 이해가 갈 것이다. floor는 "마루, 바닥"이라는 뜻이고 ceil은 "천장"이라는 뜻인데 단어뜻과 연관지어 보면 자연스럽게 이해가 될 것이다.

실수 x 반올림한 = floor(x+0.5)
소수점 둘째자리 반올림 값 = floor(x*10+0.5)/10

 
5) 절대값 함수

절대값 함수는 인수의 부호를 강제로 양수로 바꾼다. 즉 3은 그냥 3으로 두고 -3은 3으로 바꾸는 것이다. 인수의 타입에 따라 3가지 함수가 준비되어 있다. 이외에 복소수 타입에 대한 절대값 함수도 있으나 여기서는 다루지 않기로 한다. 

int abs(int n);
long labs(long n);
double fabs(double x);

위에서부터 순서대로 정수형, long형, 실수형에 대한 절대값을 구한다.


2. 난수 함수

1) 표준 난수 함수

난수(Random Number)란 무작위로 만들어지는 알 수 없는 값이다. 마치 주사위를 던졌을 때 어떤 수가 나올지 미리 알수 없는 것처럼 말이다. 어떤 값을 가지게 될 지 예측할 수 없는 수라는 뜻인데 이런 난수가 필요한 이유는 말 그대로 예측을 허용하지 않기 위해서이다.

만약 포커 게임을 만드는데 게임을 할 때마다 나오는 패가 동일하다면 이 게임은 정말 재미없을 것이다. 또한 슈팅 게임에서 적이 움직이는 경로에 일정한 규칙이 있다거나 퍼즐 게임의 퍼즐이 예측 가능하다면 이 또한 제대로 된 게임이라고 할 수 없다. 패를 무작위로 섞기 위해, 적의 움직임을 미리 알 수 없도록 하기 위해 난수가 필요하다.

난수를 만들 때는 일반적으로 random 이라는 함수를 사용하며 난수 루틴을 초기화할 때는 randomize라는 함수를 사용한다. 그러나 이 함수들은 진짜 함수가 아니라 매크로로 정의되어 있는 가짜 함수들이다. 가짜 함수만 쓸 수 있어도 난수를 만드는데는 큰 불편함이 없지만 내부를 좀 더 정확하게 이해하기 위해 이 매크로 함수들을 분석해 보자. 난수를 만드는 진짜 함수는 다음 두 개이다.

int rand(void);
void srand(unsigned int seed);

rand 함수는 0~RAND_MAX 범위의 수 중에서 무작위로 한 수를 생성해 낸다. RAND_MAX는 컴파일러에 따라 다르지만 일반적으로 32767(0x7ffff)로 정의되어 있다. 그래서 rand 함수를 호출하면 0부터 32767중의 임의의 정수 하나가 리턴된다.

#define randomize() srand((unsigned)time(NULL))  // 완전 난수

randomize 함수는 현재 시간을 사용하여 난수 발생기를 초기화하며 random 함수는 인수로 전달된 n사이의 난수를 발생시킨다. rand, srand 함수보다 훨씬 더 직관적이고 원형이 간단하기 때문에 아주 옛날부터 난수 생성을 위해 이 두 매크로 함수를 사용하는 것이 정석이었다. 그래서 볼랜드사의 터보 C, 볼랜드 C 계열 컴파일러는 이 두 함수를 stdlib.h 헤더 파일에 정의해 놓았다.

그러나 볼랜드 이외의 컴파일러들은 이 매크로를 헤더 파일에 정의해 놓지 않아서 rand, srand 함수를 직접 사용해야 하는 불편함이 있다. 하지만 컴파일러가 제공하지 않는다고 randomize, random 함수를 못 쓰는 것은 아니며 필요하면 이 매크로를 직접 정의해서 사용할 수 있다. 그래서 이 책은 Turboc.h 헤더 파일에 이 두 매크로를 미리 정의해 놓았으며 이 헤더만 포함하면 터보 C를 쓰듯이 두 함수를 자유롭게 사용할 수 있다. 만약 실전에서 이 두 함수가 필요하면 Turboc.h에 있는 매크로 정의문을 복사해서 사용하면 된다.

2) 난수의 생성

random 함수 자체는 간단하지만 응용하기에 따라서는 아주 다양한 유형의 난수를 만들 수 있다. 유형별로 random 함수의 응용예를 보도록 하자.

(1) 0~n사이의 난수는 random(n)으로 생성한다. 이때 생성되는 난수의 범위에 인수 그 자체는 제외되며 난수 중 제일 큰 값은 n-1이다.

random(10)       // 0~9 까지의 난수
random(89)       // 0~88 까지의 난수

(2) random 함수가 만들어내는 난수의 최소값은 항상 0으로 고정되어 있다. 난수 범위의 끝 값은 인수 n으로 조정하며 범위의 시작값은 random 호출 결과에 상수를 더해 조정한다.

random(10)+1         // 1~10까지의 난수
random(20)+10   // 10~29 까지의 난수

random 함수로 생성한 난수에 상수를 더하면 난수의 범위가 평행이동된다.

(3) 난수의 범위가 평행 이동되면 범위의 끝도 같이 이동되므로 미리 계산에 포함하여 범위도 적당히 줄여야 한다. 5~10 사이(10은 제외)의 난수를 만들고 싶다고 해서 random(10)+5라고 호출해서는 안되며 random(5)+5라고 호출해야 한다. 일정한 범위의 난수 생성문을 일반적으로 정의하면 다음과 같다.

a~b사이(b 제외)의 정수 난수를 구할 때 : random(b-a)+a;
a~b까지(b 포함)의 정수 난수를 구할 때 : random(b-a+1)+a;

(4) 난수 사이의 간격은 난수를 구한 후 곱을 사용한다. 이때 범위를 지정하는 인수는 곱해주는 수를 미리 나누어 구해야 한다. 만약 0~100 미만의 짝수 중 하나를 구하고자 한다면 다음과 같이 한다.

random(100/2)*2

100/2는 50이므로 random 함수에 의해 0~49사이의 난수가 생성되며 이 값에 2를 곱하면 0~98로 범위가 확장된다. 정수에 2를 곱했으니 생성된 난수는 모두 짝수일 수밖에 없다. 만약에 홀수를 구하고 싶다면 1을 더하면 될 것이다.

(5) 실수 난수가 필요하면 먼저 충분한 크기의 정수 난수를 구하고 필요한 유효자리수만큼 10의 거듭승으로 나눈다. 소수점 한자리까지 유효한 0.0~9.9사이의 난수는 다음과 같이 생성하면 된다.

random(100)/10.0

random(100)에 의해 0~99까지의 정수가 생성되는데 이 값을 10.0으로 나누면 0.0~9.9까지로 범위가 축소될 것이다. 이때 나누어주는 수는 반드시 실수 상수여야 / 연산자가 실수 나눗셈을 하게 된다. 소수점 두 자리까지 유효한 실수 난수는 0~1000까지 정수 난수를 구한 후 100.0으로 나누면 된다.

(6) 분리된 범위의 난수도 원한다면 생성할 수 있다. 다음 예는 0~4, 14~18 사이의 두 범위에 있는 수 중 하나를 골라준다.

(random(5)+5)*(random(2)==0 ? 1:-1)+9

(random(2)==0 ? 1:-1) 연산문은 앞에서 생성한 난수의 부호를 난수로 선택하는 역할을 한다. random(2)가 0이라는 표현은 1/2의 확률을 의미한다. 사실 이 예는 좀 억지스럽고 실용성이 없지만 이런 식으로도 응용할 수 있다는 것을 보여주기에는 충분하다.

(7) 전혀 연관성이 없는 수들 중 하나를 난수로 선택할 수도 있다. 예를 들어 3, 7, 12, 15 중 하나를 선택하고 싶다고 한다면 다음과 같이 하면 된다.

int i;
do {
 
    i=random(16);
} while (i!=3 && i!=7 && i!=12 && i!=15); 

원하는 난수가 나올 때까지 루프를 계속 돌리기만 하면 된다. 다음 장에서 배울 배열을 사용하면 배열에 원하는 값들을 넣어 놓고 배열의 첨자를 난수로 고를 수도 있다. 이런 식으로 제어구조까지 활용하면 사실 못만들어낼 난수가 없는 셈이다.

난수의 활용 용도는 무궁 무진한데 불규칙한 수의 생성 뿐만 아니라 확률을 제어하고 싶을 때도 사용된다. if (random(n) == 0) { } 조건문은 일정한 확률로 어떤 문장을 실행한다. 예를 들어 if (random(10) == 0) 은 열번에 한 번꼴로, 10%의 확률로 참이 된다. 난수의 범위가 넓을수록 확률은 작아지고 좁을수록 확률이 커진다. 이때 ==0은 별 의미가 없으며 1이나 2와 비교를 해도 똑같은 결과를 얻을 수 있다.


3. 시간 함수

1) time

컴퓨터안에는 시계가 내장되어 있어 항상 정확한 시간을 유지하고 있는데 프로그램에서 시간을 필요로 할 경우 시간 함수로 이 값을 조사할 수 있다. 또한 조사한 시간을 목적에 맞게 조정하거나 변환 및 포맷팅할 수도 있다. 모든 시간 함수의 원형은 time.h 헤더 파일에 선언되어 있으므로 시간 관련 함수를 사용하려면 반드시 time.h를 인클루드해야 한다. 이 책에서 사용하고 있는 Turboc.h가 미리 time.h를 인클루드하고 있으므로 여기서는 그럴 필요가 없지만 실전에서는 그렇지 않음을 명심하자. 시간과 관련된 가장 기본적인 함수는 현재 시간을 구하는 time 함수이다.

time_t time( time_t *timer );
char *ctime( const time_t *timer );

time 함수는 1970년 1월 1일 자정 이후 경과한 초를 조사하는데 리턴 타입인 time_t형은 시스템에 따라 달라지며 윈도우즈에서는 4바이트 정수(typedef long time_t;)로 정의되어 있다. time 함수는 time_t형의 포인터를 인수로 받아 이 인수에 조사된 시간을 채워 주기도 하고 같은 값을 리턴하기도 한다. 둘 중 아무값이나 사용해도 상관없으며 리턴값만 사용할 경우는 인수로 NULL을 전달할 수도 있다. 다음 두 코드는 동일하다.

time_t now
now=time(NULL);

time_t now
time(&now);

이 함수는 최대 2038년 1월 18일까지의 날짜를 표현할 수 있으며 64비트 버전인 _time64 함수는 3000년 12월 31일까지 표현 가능하다. 이 함수가 조사하는 시간은 초단위이기 때문에 이 값으로부터 우리가 일상적으로 사용하는 시간을 바로 구하기는 무척 어렵다. 또한 세계 표준시인 UTC 포맷으로 되어 있어 우리나라 시간과 일치하지도 않는다.

ctime 함수는 time_t형의 경과초를 출력하기 편리한 문자열 형태로 바꾸며 UTC로 된 시간을 지역 설정에 맞게 조정해 주기도 한다. 지역 설정이란 각 국가의 경도에 따른 세계 표준시와의 차이점과 일광 절약 시간(Daylight Saving time;흔히 Summer Time이라고 한다)의 운영 여부 등에 따라 달라지는데 우리나라의 경우 세계 표준시보다 9시간 더 빠르다.

변환된 문자열은 26문자 길이로 되어 있으며 끝에 개행 문자가 있어 printf 등의 함수로 곧바로 출력할 수 있다.

실행 결과는 다음과 같다. 이 실행 결과를 보면 저자가 일요일 새벽에도 잠을 자지 못하고 원고를 열심히 쓰고 있음을 알 수 있다.

현재 시간은 Sun Sep 05 03:35:27 2004
입니다.

 초단위로 된 시간을 문자열 형태로 변환하므로 읽기는 편하지만 영문으로 출력되는데다 개행 코드가 작성되어 있어 다른 문자열 중간에 삽입하려면 개행 코드를 지운 후 사용해야 하는 번거로움이 있다. 다음 두 함수는 날짜와 시간을 문자열 형태로 바로 구하는 좀 더 간단한 함수이다. 

char *_strdate(char *datestr);
char *_strtime(char *timestr); 

_strdate는 날짜를 MM/DD/YY 포맷으로 구해 datestr 버퍼에 복사하며 _strtime은 시간을 HH:MM:SS 포맷으로 구해 timestr 버퍼에 복사하는데 이 함수가 구해주는 시간은 24시간제이다. 두 함수로 전달되는 버퍼는 널 문자까지 고려하여 최소한 9바이트 이상이어야 한다. ctime이 변환 결과를 저장하기 위해 사용하는 버퍼는 라이브러리에서 미리 할당해 놓은 정적 메모리 영역이며 이 영역은 asctime, gmtime, localtime 등의 함수들이 공유한다. 따라서 상기 함수 중 하나를 호출하면 다른 함수가 작성한 문자열은 파괴되므로 변환한 문자열을 계속 사용하려면 사본을 복사해 두어야 한다.

시간 관련 함수들이 버퍼를 공유하는 이런 설계는 이후 멀티 스레드에서 문제거리가 된다. C 라이브러리 함수를 만들 때는 멀티 스레드라는 것이 없었기 때문에 이런 점을 미처 고려하지 못했다.


2) 시간 구조체

time 함수를 사용하면 현재 시간을 쉽게 구할 수 있고 ctime을 사용하면 이 시간을 문자열로도 바꿀 수 있지만 포맷팅을 마음대로 할 수 없어 무척 불편하다. 시간 포맷을 자유롭게 변경하고 싶다면 경과초 형태로 되어 있는 값에서 각각의 시간 요소를 분리해야 한다. 다음 함수들은 time_t형의 값을 tm 구조체로 변환한다. 

struct tm *gmtime(const time_t *timer);
struct tm *localtime(const time_t *timer);
time_t mktime(struct tm *timeptr); 

gmtime, localtime 함수는 둘 다 time_t형의 값을 tm 구조체로 변환하는데 gmtime은 세계 표준시로 변환하며 localtime은 지역시간으로 변환한다. 세계 표준시는 잘 사용되지 않으므로 localtime 함수가 훨씬 더 자주 사용된다. 이 두 함수도 라이브러리에 정적으로 할당되어 있는 tm 구조체를 사용하므로 한 함수가 구해 놓은 정보는 다른 함수를 호출하면 파괴된다. mktime 함수는 반대의 변환을 하는데 tm 구조체를 time_t형으로 바꾼다. tm 구조체는 time.h 헤더 파일에 다음과 같이 선언되어 있다.

struct tm {
 
       int tm_sec;     /* seconds after the minute - [0,59] */
        int tm_min;     /* minutes after the hour - [0,59] */
        int tm_hour;    /* hours since midnight - [0,23] */
        int tm_mday;    /* day of the month - [1,31] */
        int tm_mon;     /* months since January - [0,11] */
        int tm_year;    /* years since 1900 */
        int tm_wday;    /* days since Sunday - [0,6] */
        int tm_yday;    /* days since January 1 - [0,365] */
        int tm_isdst;   /* daylight savings time flag */
}; 

날짜와 시간을 구성하는 여러 가지 멤버들이 포함되어 있으며 주석도 비교적 상세하게 작성되어 있다. 각 멤버의 이름이 무척 쉽게 작성되어 있어 따로 외울 필요까지는 없지만 멤버마다 베이스가 제각각이므로 쓸 때는 조금 주의해야 한다.

멤버

설명

tm_sec

(0~59)

tm_min

(0~59)

tm_hour

시간(0~23)

tm_mday

날짜(1~31)

tm_mon

(0~11)

tm_year

1990 이후 경과 년수

tm_wday

요일(0~6). 0 일요일

tm_yday

년중 날짜(0~365)

tm_isdst

일광 절약 시간과의

 

#include <Turboc.h>

void main()
{
     time_t t;
     tm *pt; 

     time(&t);
     pt=localtime(&t);

     printf("현재 시간 %d년 %d월 %d일 %d시 %d분 %d초입니다.\n",
          pt->tm_year+1900,pt->tm_mon+1,pt->tm_mday,
          pt->tm_hour,pt->tm_min,pt->tm_sec);;
}

현재 시간 2004년 9월 5일 4시 12분 56초입니다.

시간 요소 사이에 한글을 넣을 수도 있고 시간 요소의 출력 순서를 마음대로 조정할 수 있어서 훨씬 더 자유롭고 깔끔한 출력을 할 수 있다. asctime 함수는 tm 구조체를 문자열로 바꾸는데 ctime 함수와 마찬가지로 출력 결과가 영어로 되어 있어 한글 환경에는 실용성이 없고 개행 문자도 포함되어 있다.

char *asctime(const struct tm *timeptr);
size_t strftime(char *strDest, size_t maxsize, const char *format, const struct tm *timeptr); 

strftime 함수는 시간을 다양한 방식으로 포맷팅하는데 첫 번째 인수로 버퍼, 두 번째 인수로 버퍼의 길이, 세 번째 인수로 포맷팅 방식, 네 번째 인수로 tm 구조체를 준다. 세 번째 인수에 포맷팅 서식을 어떻게 지정하는가에 따라 시간을 다양한 형식의 문자열로 바꿀 수 있다.

#include <Turboc.h>

void main()
{

     time_t t;
     char Format[128];

      time(&t);
     strftime(Format,128,"%Y %B %d %A %I:%M:%S %p",localtime(&t));
     puts(Format);
}



3) 기타 시간 함수

시간은 여러 모로 쓸 데가 많은 정보이다. 다음 함수는 프로그램이 실행을 시작한 후의 경과된 시간(Process Time)을 조사한다.

clock_t clock( void );       

clock_t 타입은 long형으로 정의되어 있으며 이 함수가 조사한 값을 CLOCKS_PER_SEC으로 나누면 프로그램 실행 후의 경과 초를 알 수 있다. 이 값은 시스템에 따라 다른데 윈도우즈에서는 1000으로 정의되어 있다.

typedef long clock_t;
#define CLOCKS_PER_SEC  1000 

실행 후의 경과 시간 자체는 별로 쓸 데가 없지만 두 작업 시점간의 시간을 계산하거나 일정한 시간만큼 특정 작업을 계속하고 싶을 때 clock 함수가 조사하는 시간이 기준점으로 사용될 수 있다.

delay도 정확한 시간을 지연시키기는 하지만 기다리는동안 다른 일을 할 수 없다는 점이 다르다. 시스템 속도에 상관없이 일정 시간동안 어떤 작업을 하고 싶다면 clock 함수로 구한 시간을 이용하면 된다. 다음 함수는 두 시간값의 차를 구해준다.

double difftime(time_t timer1, time_t timer0);

실수형을 리턴하는 것으로 되어 있지만 계산 결과가 초단위로 되어 있기 때문에 정밀한 시간 계산이나 코드의 성능 측정 등에 쓰기에는 무리가 있다.

출처: http://winapi.co.kr/

'old > C Grammer' 카테고리의 다른 글

기억 부류  (0) 2010.11.18
함수  (0) 2010.11.17
연산자  (0) 2010.11.16
제어문  (0) 2010.11.15
변수  (0) 2010.11.12
Posted by jazzlife
,