제 34강) 라이브러리 함수2 |
오늘은 "강의에서 다루지 않았던"의 네번째 시간입니다.
이번 시간에는 라이브러리 함수2에 대해서 다뤄보려고 합니다.
문자 함수(ctype.h) |
문자 하나를 다루는 함수입니다.
여기서 정의되는 모든 함수는 참일 경우에는 0이 아닌 int 값을 반환하고, 거짓일 경우에는 0을 반환하는 성질을 가졌습니다.
먼저 isalnum과 isalpha를 보겠습니다.
#include <ctype.h> // 여기서 설명하는 모든 함수는 ctype.h에 정의되어 있습니다.
int isalnum (int c);
c가 영문자(대 + 소) 또는 숫자인지 판단
=> if (isalnum(65)) // 이때 65는 대문자 A를 나타내기 때문에 참
int isalpha (int c);
c가 영문자(대 + 소)인지 판단
=> if (isalpha(50)) // 이때 50은 숫자 2를 나타내기 때문에 거짓
isalnum은 "is alphabet or number" 이구요, isalpha는 "is alphabet"입니다.
함수 이름만으로도 쉽게 판단할 수 있습니다.
(그러므로 여러분도 함수 이름을 정할 때 쉽게 파악할 수 있도록 만드세요.)
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char str[] = "2018: c, c++ is perfect language!";
int countAlnum = 0;
int countAlpha = 0;
int length = sizeof(str) / sizeof(char);
for (int i = 0; i < length; i++)
{
// 숫자나 영문자일 경우에
if (isalnum(str[i]))
{
countAlnum++;
}
// 영문자일 경우에
if (isalpha(str[i]))
{
countAlpha++;
}
}
printf("%s\n", str);
printf("isalnum : %d\n", countAlnum);
printf("isalpha : %d\n", countAlpha);
return 0;
}
isalnum과 isalpha에 관한 예제입니다.
결과는 위와 같습니다.
다음은 5가지를 한 번에 볼겁니다.
isdigit, isgraph, isprint, isspace, ispunct 입니다.
#include <ctype.h> // 여기서 설명하는 모든 함수는 ctype.h에 정의되어 있습니다.
int isdigit (int c);
숫자(0 ~ 9)인지 판단
=> if (isdigit(55)) // 이때 55는 숫자 7이기때문에 참
int isgraph (int c);
c가 공백문자(' ')를 제외한 것들 중에 그래픽적으로 표현될 수 있는지 판단
=> 예제에서 다룹니다.
int isprint (int c);
c가 공백문자를 포함한 것들 중에 그래픽적으로 표현될 수 있는지 판단
=> 예제에서 다룹니다.
int isspace (int c);
c가 화이트스페이스(White-space)인지 판단
=> 예제에서 다룹니다.
int ispunct (int c);
c가 구두점 문자(punctuation character)인지 판단
(Standard C에서는 숫자, 영문자를 제외한 모든 그래픽적으로 표현될 수 있는 문자를 구두점 문자로 봅니다.)
=> 예제에서 다룹니다.
예제를 보기 전에 몇가지를 먼저 봅시다.
' ' | (0x20) | space (SPC) |
'\t' | (0x09) | horizontal tab (TAB) |
'\n' | (0x0a) | newline (LF) |
'\v' | (0x0b) | vertical tab (VT) |
'\f' | (0x0c) | feed (FF) |
'\r' | (0x0d) | carriage return (CR) |
(White-space 표 출처: http://www.cplusplus.com/reference/cctype/isspace/)
위의 표는 White-space 를 나타낸 표입니다.
isspace에서 위의 White-space를 인식합니다.
예제를 봅시다.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char str[] = "2018: c, c++ is perfect language!\n but java, c# is perfect too!";
int countDigit = 0;
int countGraph = 0;
int countPrint = 0;
int countPunct = 0;
int countSpace = 0;
int length = sizeof(str) / sizeof(char);
for (int i = 0; i < length; i++)
{
// 숫자일 경우에
if (isdigit(str[i]))
countDigit++;
// 그래픽적으로 표현이 가능한 문자일 경우에(공백 미포함)
if (isgraph(str[i]))
countGraph++;
// 그래픽적으로 표현이 가능한 문자일 경우에(공백 포함)
if (isprint(str[i]))
countPrint++;
// 구두점 문자일 경우에
if (ispunct(str[i]))
countPunct++;
// White-space일 경우에
if (isspace(str[i]))
countSpace++;
}
printf("%s\n", str);
printf("isdigit : %d\n", countDigit);
printf("isgraph : %d\n", countGraph);
printf("isprint : %d\n", countPrint);
printf("ispunct : %d\n", countPunct);
printf("isspace : %d\n", countSpace);
return 0;
}
위에서 소개했던 5가지 함수를 예제에 담아보았습니다.
하지만 어떤 것이 isdigit에, isgraph에, isprint에, ispunct에, isspace에 들어갔는지 확인하기 위해서 예제를 조금 바꾸어봅시다. 코드가 살짝 비 효율적으로 바뀌긴 하지만 O(n)에서 O(5n)으로 바뀌는 것뿐이기 때문에 그냥 해봅시다.
#include <stdio.h>
#include <ctype.h>
// str : 분석할 문자열 배열
// length : 분석할 배열의 길이
// func : 조건문에서 사용할 함수
// out : 조건문에서 함수 func를 이용하여 개수를 새어 저장할 변수
// name : 처음 출력시 보여줄 이름
void forfor(char* str, int length, int(*func)(int), int* out, char* name)
{
printf("[%s]: ", name);
for (int i = 0; i < length; i++)
{
if (func(str[i]))
{
*out += 1;
printf("%#x ", str[i]);
}
}
printf("\n");
}
int main(void)
{
char str[] = "2018: c, c++ is perfect language!\n but java, c# is perfect too!";
int countDigit = 0;
int countGraph = 0;
int countPrint = 0;
int countPunct = 0;
int countSpace = 0;
printf("원문장: %s\n\n", str);
int length = sizeof(str) / sizeof(char);
forfor(str, length, isdigit, &countDigit, "isdigit");
forfor(str, length, isgraph, &countGraph, "isgraph");
forfor(str, length, isprint, &countPrint, "isprint");
forfor(str, length, ispunct, &countPunct, "ispunct");
forfor(str, length, isspace, &countSpace, "isspace");
printf("\n");
printf("isdigit : %d\n", countDigit);
printf("isgraph : %d\n", countGraph);
printf("isprint : %d\n", countPrint);
printf("ispunct : %d\n", countPunct);
printf("isspace : %d\n", countSpace);
return 0;
}
예전에 배웠던 함수 포인터를 사용하여 코드 재활용을 높였습니다.
이렇게 예제가 바뀌었습니다.
이전에는 개수만 나왔다면 이제는 어떤것을 숫자를 세었나 확인하도록 해당 문자의 16진수를 출력하도록 하였습니다.
이번에는 4가지의 변수를 봅니다.
islower, isupper, tolower, toupper입니다.
#include <ctype.h> // 여기서 설명하는 모든 함수는 ctype.h에 정의되어 있습니다.
int islower (int c);
c가 영문자 중 소문자인지 판단
=> if (islower(65)) // 이때 65는 대문자 A이므로 거짓
int isupper (int c);
c가 영문자 중 대문자인지 판단
=> if (isupper(65)) // 이때 65는 대문자 A이므로 참
int tolower (int c);
c를 영문자 소문자로 변환하여 반환
=> int a = tolower(65); // 65인 대문자 A를 소문자 a인 97로 변환하여 반환
int toupper (int c);
c를 영문자 대문자로 변환하여 반환
=> int A = toupper(97); // 97인 소문자 a를 대문자 A인 65로 변환하여 반환
이제 예제를 보도록 합시다.
#include <stdio.h>
#include <ctype.h>
// str : 분석할 문자열 배열
// length : 분석할 배열의 길이
// if_func : 조건문에서 사용할 함수
// func : 조건문을 만족할 때 작용하는 함수
// name : 처음 출력시 보여줄 이름
void forfor(char* str, int length, int(*if_func)(int), int(*func)(int), char* name)
{
int c;
printf("[%s]: ", name);
for (int i = 0; i < length; i++)
{
c = str[i];
if (if_func(c) == 0)
{
c = func(c);
}
printf("%c", c);
}
printf("\n");
}
int main(void)
{
char str[] = "2018: C, C++ is Perfect Language!\n but Java, C# is Perfect too!";
int length = sizeof(str) / sizeof(char);
printf("원문장: %s\n\n", str);
forfor(str, length, islower, tolower, "lower");
forfor(str, length, isupper, toupper, "upper");
return 0;
}
위의 예제 또한 함수 포인터를 사용하였습니다.
수학 함수(math.h) |
수학을 다루는 함수입니다.
먼저 삼각함수입니다.
#include <math.h> // 여기서 설명하는 모든 함수는 math.h에 정의되어 있습니다.
double cos (double x);
float cosf (float x);
long double cosl (long double x);
삼각함수에서 cos(x)를 뜻합니다.
double sin (double x);
float sinf (float x);
long double sinl (long double x);
삼각함수에서 sin(x)를 뜻합니다.
double tan (double x);
float tanf (float x);
long double tanl (long double x);
삼각함수에서 tan(x)를 뜻합니다.
이 삼각함수를 사용하기 위해서는 각도를 변환하여 넣어줘야 하는데요.
예제를 봅시다.
#include <stdio.h>
#include <math.h>
// angle : 각도
// func : 삼각함수
double triangleFunction(int angle, double(*func)(double))
{
const double PI = 3.1415926535;
return func((PI * angle) / 180.0);
}
int main(void)
{
int angle = 30;
printf("사인 %d : %f\n", angle, triangleFunction(angle, sin));
printf("코사인 %d : %f\n", angle, triangleFunction(angle, cos));
printf("탄젠트 %d : %f\n", angle, triangleFunction(angle, tan));
return 0;
}
9번줄에 보시면 각도를 그대로 넣어주는 것이 아닌 PI와 곱해서 180으로 나눕니다.
(PI는 3.1415926535 입니다.)
즉, 30도를 넣는다고 해서 그대로 30을 넣으면 안되고 변환하여 넣어야합니다.
(이것은 공식입니다, 삼각함수(파이 * 각도 / 180))
다음은 나머지 수학에 관련된 함수들입니다.
#include <math.h> // 여기서 설명하는 모든 함수는 math.h에 정의되어 있습니다.
int abs (int n);
n의 절댓값을 반환
(abs는 math.h와 stdlib.h에 선언되어 있으며 C언어일때의 abs와 C++일때의 abs는 조금 다릅니다.)
=> int numAbs = abs(-55); // numAbs = 55;
double exp (double x);
float expf (float x);
long double expl (long double x);
지수계산을 함(e^x)
=> double result = exp(5.0); // result = 148.413159;
double fabs (double x);
float fabsf (float x);
long double fabsl (long double x);
실수 x의 절대값 계산
=> double d = fabs(-3.222); // d = 3.222;
double floor (double x);
float floorf (float x);
long double floorl (long double x);
소수점 아래를 내려버리는데 음의 소수일 경우에는 한 값 아래로 내림
=> double d1 = floor(3.5); // d1 = 3.000000;
=> double d2 = floor(-3.5); // d2 = -4.000000;
double fmod (double numer, double denom);
float fmodf (float numer, float denom);
long double fmodl (long double numer, long double denom);
numer를 denom으로 나눈 나머지를 반환
=> double d = fmod(3.0, 4.0); // d = 3;
double log (double x);
float logf (float x);
long double logl (long double x);
자연로그를 계산함
=> double result = log(5.5); // result = 1.704748;
double log10 (double x);
float log10f (float x);
long double log10l (long double x);
상용로그를 계산함
=> double result = log10(100.0); // result = 2.000000;
double modf (double x, double* intpart);
float modff (float x, float* intpart);
long double modfl (long double x, long double* intpart);
x의 정수부분을 intpart에 반환하고 자기자신은 소수점아래 실수부분 반환
=> double part = modf(3.141592, &intpart); // intpart = 3.000000, part = 0.141592;
double pow (double base, double exponent);
float powf (float base, float exponent);
long double powl (long double base, long double exponent);
base의 exponent승 계산
=> double popo = pow(2, 10); // popo = 1024.000000;
수학함수에서 자주쓰이는 것들을 모아보았습니다.
사용법은 위와 같습니다.
다음 시간에는 |
다음 시간에는 마지막으로 시간 라이브러리(time.h)에 대해서 알아보겠습니다.
'Study > C언어' 카테고리의 다른 글
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 38 [정렬 알고리즘(삽입 정렬)] (0) | 2020.01.29 |
---|---|
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 35 [라이브러리 함수3(날짜 및 시간, time.h)] (3) | 2019.02.16 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 33 [라이브러리 함수1(변환, 랜덤)] (0) | 2019.02.16 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 32 [다루지 않았던2(Call by ~)] (0) | 2018.10.28 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 30 [전역변수와 정적변수(static)] (0) | 2018.10.28 |