93 – 절대값 함수

절대값을 구하는 함수는 각각의 형태에 따라서 각각의 함수가 따로 존재한다. 단, floating point를 이용하여 구해야 하는 double형의 경우에는 math.h에 구현되어 있다. (소수점 계산 작업 자체가 상당히 복잡한 구조라서 쉽게 할 수 없다.)

  • 함수 이름 | 기능
  • abs | int형 데이터의 절대값을 구한다.
  • labs | long int형 데이터의 절대값을 구한다.
  • fabs | double형 데이터의 절대값을 구한다.

예시를 보면 쉽게 알 수 있다.

스크린샷 2017-05-06 오후 4.27.22

92 – 수학 함수

수학 함수는 여러곳에서 사용되는 함수들이다. 기본적으로 컴퓨터의 존재가 계산을 위해 존재하는 함수이고, 비즈니스의 관점에서 또한 기본적인 수학 작업에 대한 요구는 끊임없이 요구되고 있다. POS, 전산관리 프로그램, 재정 관리 프로그램 등 비즈니스를 위해 기본적으로 이용되는 도구들 또한 컴퓨터에서 중요한 기능이기 때문에 절대로 빠질 수 없는 기능이 수학 관련된 함수이다.

전자상거래, 인터넷 뱅킹 등이 보편화됨녀서 서비스를 안전하게 제공하기 위해 암호화 기술들이 개발되는데, 이 또한 수학으로 이루어진 것이기 때문에 수학 함수는 중요하다. 게임 제작에서도 빠질 수 없다.

이렇게 보면 수학 관련된 함수에 대해서는 상당히 중요하다는 것을 알 수 있다. 그 중에서도 여러모로 많이 쓰는 수학 함수에 대해서 한번 쭉 짚고 넘어가자.

91 – 기타 입출력 함수

이 외에도 입출력에 관한 여러 함수들이 존재한다. 그 중에서도 좀 알아두면 유용할 것 같은 함수들을 정리해보겠다.

파일의 경우에는 읽고 쓰는 도중에 오류가 발생할 수 있는데, 이런 오류 함수들을 알아두면 좋을 거 같다. 파일로부터 더 이상 읽을 데이터가 없는지 또는 파일에 대한 동작이 제대로 이루어졌는지에 대한 점검을 쉽게 해주는 파일 오류 관련된 함수들이 존재한다.

파일 오류와 관련된 함수들로는 eof(end of file)인지, 파일 자체 오류인지, 오류 정보와 끝 정보를 초기화하는 그런 작업이 필요하다.

  • 함수 이름 | 기능
  • feof | 파일의 끝인지 확인한다.
  • ferror | 파일이 오류인지를 확인한다.
  • clearerr | 파일의 끝과 오류 정보를 초기화한다.

이런 함수 사용의 예시를 한번에 몰아서 작성해봤다. 읽기 전용 파일에 데이터를 쓰려고 하면 오류가 발생, 그 다음에 오류가 확인되고, 오류 정보를 clearerr를 사용해서 해제하는 예시를 작성하였다. 전체적인 흐름을 확인할 수 있어야 한다.

또한 파일을 읽고 쓰는 데 있어서도 처음부터 줄줄이 다 읽을 수는 없다. 주문형 비디오 서비스(VOD)를 예로 들어보자. 사용자가 원하는 부분 혹은 이전에 보던 부분에서 이어보기를 제공해 주는데, 이를 위해서는 특정 위치에서 읽을 수 있도록 해주기 때문이다. 파일 입출력에는 이런 기능들이 들어있고, 오래전부터 사용하던 C언어 또한 이런 입출력 함수를 가지고 있다.

  • 함수 이름 | 기능
  • ftell | 파일의 읽기/쓰기 포인터 값을 구한다.
  • rewind | 파일의 읽기/쓰기 포인터를 처음으로 되돌린다.

source 파일에 “ABCDEF”라는 데이터가 있다고 할 때, 파일을 읽은 다음에 한 문자씩 읽어서 읽은 값의 포인터 위치를 출력하는 예제를 작성하였다. 두번의 과정을 거쳐서 첫번째로 읽은 값은 포인터의 배열 위치가 2가 되었고, 그 다음에 원래대로 되돌려서 0번(처음) 위치를 가리키고 있다.

그리고 함수의 읽기/쓰기 포인터를 임의의 위치로 설정하는 함수 또한 존재한다. 어디를 기준으로 할 지에 대해서 특정 offset만큼 이동해서 처리할 수 있도록 해주는 것이다.

  • 함수 이름 | 기능
  • fseek | 파일의 읽기/쓰기 포인터를 임의의 위치로 설정한다.

이 함수의 두 번째 인수값이 offset 값인데, 의미가 있다.

  • whence | 의미
  • SEEK_SET | 파일의 시작
  • SEEK_CUR | 현재 읽기/쓰기 포인터 위치
  • SEEK_END | 파일의 끝

사용 예시를 보면 이 함수가 어떻게 이용되는지 알 수 있을 것이다. 시작 위치에서 우측으로 10칸 이동시킨 다음, 파일의 끝에서 읽어서 화면에 출력하는 예시이다.

90 – 파일 입출력 함수

표준 입출력을 통한 방식 이외에도 파일을 통한 데이터의 입력 및 출력이 있을 수 있다. 파일을 통해 입출력을 하기 위해서는 사용하고자 하는 파일을 열어야 하는데 이 때 사용하는 함수가 fopen, 사용이 끝난 파일은 닫아줘야 하는데 이 때 사용하는 함수가 fclose이다.

  • 함수 이름 | 의미
  • fopen | 파일을 연다
  • fclose | 파일을 닫는다

파일을 열 때에는 여는 파일에 대해서 어떠한 형태로 사용할지를 나타내줘야 한다. 그래서 fopen 함수는 두 번째 인수로 어떤 형태로 사용할지를 적어줘야 하는데, 적어주는 인수값과 의미가 다음과 같다.

  • 인수값 | 의미
  • r | 읽기 전용. 파일 존재해야 함.
  • w | 쓰기 전용. 파일이 없어도 되며, 만약 이미 존재한다면 기존 내용이 지워짐.
  • a | 추가용. 파일이 없어도 되며, 만약 임미 존재한다면 기존 내용 뒤에 추가됨.
  • rb | 바이너리 파일의 읽기 전용.
  • wb | 바이너리 파일의 쓰기 전용.
  • ab | 파이너리 파일의 추가용.
  • r+ | 읽기와 쓰기용.
  • w+ | 쓰기와 읽기용.
  • kyuling이라는 파일을 읽기 전용으로 사용하기 위해서는 다음과 같이 작성하면 된다. 대신 쓰기 작업을 할 수 없게 된다.

fopen(“kyuling”, “r”);

게다가 한 프로그램에서 동시에 열어서 사용할 수 있는 파일의 수는 제한적이다. 따라서 사용이 끝난 파일은 닫아주는 것이 바람직하다. fclose를 이용하여 닫으면 된다.

FILE *file;
file = fopen(“kyuling”, “w”);
fclose(file);

예제를 만들어서 진행해 보았다. 예제를 따라할 때, 파일이 없을 경우에는 리눅스의 touch 명령어를 이용하여 빈 파일을 만들어서 실습을 진행하면 된다. 소스 코드 밑에 실행하던 예시 명령어를 그대로 순차적으로 찍었다. 파일이 없으면 어떻게 되는지 보여주기 위해서이다.

이제는 파일을 통해 한 문자를 입출력하는 함수를 살펴보겠다. getchar와 putchar와 같이 한 문자만을 받아오는 함수가 존재했다. 파일 입출력에도 그와 마찬가지인 파일 입출력이 존재한다.

  • 함수 이름 | 기능
  • fgetc | 파일을 통해 한 문자를 입력받는다.
  • fputc | 파일에 한 문자를 출력한다.

이 함수의 사용법 또한 예제를 확인해보자. touch로 만든 파일을 vi를 이용해서 안에 내용을 입력하면 이미 데이터가 있는 파일을 만들 수 있다. 파일 내용을 확인 하기 위해 cat 명령어를 이용하여 직접 결과 파일을 확인해보았다.

서식을 갖춘 데이터의 입출력 또한 파일 입출력 함수에도 존재한다.

함수 이름 | 기능

fscanf | 파일을 통해 서식을 갖춘 데이터를 입력받는다.

fprintf | 데이터를 서식화하여 파일로 출력한다.

예시 코드로 확인하면 쉽게 확인할 수 있다. 전체적인 구조는 비슷한 편이다. 문자열을 저장했다가 단순히 읽어오는 프로그램이다.

파일의 데이터를 대용량으로 처리해야 할 일이 생길 수 있다. fread와 fwrite 함수를 통해 데이터를 한꺼번에 입출력을 하면 많은 데이터를 한번에 처리할 수 있다.

함수 이름 | 기능

fread | 파일을 통해 데이터를 한꺼번에 입력받는다.

fwrite  | 데이터를 한꺼번에 파일로 출력한다.

단순 예제라서 데이터는 얼마 없지만, buffer로 데이터를 읽고 나서 그대로 파일로 출력하는 예제를 만들어보았다.

마지막으로 읽어들인 문자를 파일로 되돌리는 함수가 있다. 문자열을 저장하고 있는 파일에서 특정 문자를 추출하고자 한다고 하면, 파일로부터 한 문자씩 읽다가 특정 문자를 읽으면 읽은 파일로부터 그대로 되돌리고 읽어야 한다. 그런 경우에 쓰는 함수가 ungetc 함수이다. (이건 왜 쓰는지 필자는 아직 잘 모르겠다. 옛날에 쓰는 사람들이 필요해서 만들었나보다 생각중임.)

함수 이름 | 기능

ungetc | 방금 읽은 문자를 파일로 되돌린다.

위에서 살짝 설명한 상황을 예시 코드로 작성해보았다. l 혹은 L을 만남녀 그 뒤부터 되돌려서 반환한다.

89 – 기본 입출력 함수

우선은 표준 입출력 장치를 통한 입출력에 대해 정리를 할 것이다. 표준 입출력에서 말하는 표준 입력은 키보드, 표준 출력은 모니터를 의미한다.

표준 입력을 통해 한 문자를 입력하고 출력하는 함수는 다음과 같다.

  • 함수이름 | 기능
  • getchar | 표준 입력을 통해 한 문자를 입력받는다.
  • putchar | 표준 출력을 통해 한 문자를 출력한다.

문자 하나를 입력받는 작업을 계속 이어서 진행하면 문자열을 입력받는 작업으로도 진행할 수 있다. 이를 통한 예제는 다음과 같은데, 입력받은 대문자를 소문자로 전환하는 프로그램이다. 마지막 입력으로 엔터를 치면 EOF로 인식해서 입력이 끝나는 것이다.

이제 여러 문자를 입력받아 문자열 단위로 입력받는 함수를 알아보겠다.

  • 함수 이름 | 기능
  • gets | 표준 입력을 통해 한 행의 문자열을 입력받는다.
  • puts | 표준 출력에 한 행의 문자열을 출력하고 개행한다.

입력 받은 내용을 그대로 출력하는 예제를 만들어서 진행해 보았다. gets에서 입력받은 경우, 끝이라는 것을 입력받으면 NULL을 반환한다. 그래서 마지막에 입력받은 부분이 NULL인지 아닌지를 체크하는 것이다.

이 다음으로 살펴볼 함수는 우리한테 익숙한 printf와 scanf이다. 이 함수들을 이용하면 ‘서식’이 지정된 문자열을 입력 및 출력할 수 있게 된다. 서식화된 입력을 통해서는 변수에 지정할 지정 타입을 서식화 할 수 있는 것이 되고, 서식화된 출력을 통해서는 서식화된 구조 및 서식에 맞는 변수 출력을 서식화하여 출력할 수 있게 된다. 서식으로 변환되는 데 이용되는 문자열을 서식 문자열이라고 하고,  흔히 %d, %s, %f 등으로 도중 도중에 사용하던 것이다.

우선은 scanf 함수에 대해서 살펴보도록 하겠다.

  • 함수 이름 | 기능
  • scanf | 표준 입력을 통해 서식을 갖춘 데이터를 입력받는다.

그리고 scanf의 변환 문자열은 다음과 같다.

  • 변환 문자열 | 의미
  • %o | 8진수 정수 형식으로 입력
  • %d | 10진수 정수 형식으로 입력
  • %ld | long형 10진 정수 형식으로 입력
  • %x | 16진수 정수 형식으로 입력
  • %f | float형 형식으로 입력
  • %lf | double형 형식으로 입력
  • %c | 문자 형식으로 입력
  • %s | 문자열 형식으로 입력

다음으로 우리에게 친숙한 printf형을 살펴보겠다.

  • 함수 이름 | 기능
  • printf | 데이터를 서식화하여 표준 출력으로 출력한다.

그리고 printf의 변환 문자열은 다음과 같다.

  • 변환 문자열 | 의미
  • %o | 8진수 정수 형식으로 출력
  • %d | 10진수 정수 형식으로 출력
  • %ld | long형 10진수 정수 형식으로 출력
  • %x | 16진수 정수 형식으로 출력
  • %u | 부호 없는 10진 정수 형식으로 출력
  • %f | 소수점 형식으로 출력
  • %e %E | 지수 형식으로 출력
  • %g %G | %e, %f 중 짧은 쪽, 소수점에 이어지는 0은 생략
  • %c |  문자 형식으로 출력
  • %s | 문자열 형식으로 출력

printf의 출력 변환 문자열에는 출력하는 폭, 자릿수 등을 지정할 수 있다. 옵션의 지정 형식은 다음과 같다.

%폭 자릿수 변환문자

예를 들어, 숫자 123을 출력할 때, %d, %5d, %-5d에 따라서 출력이 달라지게 된다.

%d: [123]
%5d: [  123]
%-5d: [123  ]

이런 식으로 총 자릿수를 5로 지정해서 5자리의 출력 공간에 123을 출력하는 것이 두 번째 예시이고, 세 번째 예시처럼 마이너스 부호를 붙이면 뒤로 5개의 자리를 만들기 때문에 뒤에 공백이 생기게 된다.

예시는 이전까지 하면서도 많이 했지만 예의상 작성해본다.

마지막으로 메모리를 통해 입출력을 진행하는 함수를 알아보도록 하겠다. sscanf와 sprintf 함수인데,  이 함수들은 키보드를 통한 표준 입출력이 아니라 메모리 영역을 통해서 데이터를 입력받고 출력하는 함수들이다. 메모리 자체에는 그냥 값이 들어있지만 이 두 함수를 이용하면 서식화된 메모리 데이터의 입출력이 가능하다.

함수 이름 | 기능

sscanf | 메모리 영역을 통해 서식을 갖춘 데이터를 입력받는다.

sprintf | 데이터를 서식화하여 메모리 영역으로 출력한다.

이것도 예시를 보자. 데이터를 10진수와 소수점 형태로 메모리에 저장한 후, 이를 8진수와 지수 형태로 읽여들이는 예시 프로그램을 작성하였다.

88 – 입출력 함수

대부분의 프로그램이 키보드를 통해 데이터를 입력받거나 파일로부터 데이터를 읽어 이를 처리하여 처리한 결과를 화면으로 출력하거나 디스크에 파일로 저장하는 일을 한다. 입출력은 프로그램에서 자주 일어나는 동작이기 때문에 라이브러리에서는 다양한 형태의 입출력 함수를 기본으로 제공하고 있다. 이를 이용하면 큰 부담 없이 데이터를 다양한 형식으로 입력하고 출력받는 프로그램을 구현할 수 있다.

우리가 일반적으로 입력받을 때 쓰던 scanf 함수 또한 입출력 함수에 해당된다.

87 – 메모리 영역 비교 함수

메모리 영역에 저장된 내용을 비교하는 함수가 있다. memcmp가 그것인데, 특정 값 s1, s2가 가리키는 n바이트 영역의 내용을 비교해서 s1이 크면 양의 정수, 같으면 0, 적으면 음의 정수가 반환된다.

  • 함수 이름 | 기능
  • memcmp | 메모리 영역에 저장된 내용을 비교한다.

예시 프로그램을 구성했다. quit 문장이 들어오면 프로그램이 종료되는 예제 프로그램이다.

86 – 메모리 영역의 검색 함수

메모리 영역이 대해서 검색과 비교를 할 수 있는 함수가 존재한다. 메모리의 사용량이 많다면 상당히 유용한 함수들이다. 우선은 메모리 영역을 검색하는 함수에 대해서 알아보려 한다.

함수 이름 | 기능

memchr | 메모리 영역에서 임의의 문자를 검색한다.

이것도 예제를 보면 된다. 문자 ‘A’를 찾는 예제를 작성하였다.

문자 A가 시작되는 문자열을 찾아서 차례대로 출력해주고 있다. 이렇게 쭉 반복하다가 더 이상 찾지 못하면 NULL을 반환하게 되어서 while문을 빠져나가게 된다. 이를 통해 다 검색되면 NULL이 반환된다는 것도 알 수 있다.

 

85 – 메모리 영역 복사 함수

메모리 영역의 내용을 복사하는 것은 memcpy, memmove를 통해 쉽게 이용할 수 있다. 복잡한 과정을 상당히 간편하게 한 함수로, 시스템 프로그래밍을 하다 보면 많이 이용하게 될 것이다. (여러곳에서도 많이 이용한다만 필자의 경험상 시스템 프로그래밍에서 많이 이용하였다.)

  • 함수이름 | 기능
  • memcpy | 메모리 영역을 복사한다. 동일한 영역에 대한 덮어쓰기는 불가능하다.
  • memmove | 메모리 영역을 복사한다. 동일한 영역에 대한 덮어쓰기가 가능하다.

덮어쓰기 기능이 되느냐 안되느냐의 차이로 이해를 하면 쇱게 이해하여 적용할 수 있는데, 이것들도 간단하게 예제를 보고 사용법을 이해하면 될 것이다. 우선 memcpy를 이용한 방법을 보여주겟다.

memcpy를 사용하지 않았다면 for문을 이용해서 arr값을 ptr에 복사했을 것인데 memcpy를 통해 간단해졌다.

memmove의 경우에는 함수 의미가 동일하지만 덮어쓰기가 가능하다고 하였다. 그것이 어떤 차이인지를 보여줄 수 있는 예제를 만들었다. alphabet의 앞에 몇 부분을 덮어써서 복사를 한 것을 볼 수 있다.

84 – 메모리 초기화 함수

malloc으로 할당받은 메모리를 특정한 값으로 초기화하는 방법 또한 있다. 원래라면 무식하게 하나하나 다 입력을 하고 마지막에 \0을 삽입하여 문자열을 끝내는 방법을 이용할 것이다. 그런 무식한 예제가 아래와 같다.

이런 방법을 이용하지 않고 초기화를 해줄 수 있는 함수가 바로 memset이다. 이것은 포인터가 가리키는 메모리 영역의 n바이트를 특정 값으로 초기화하며, 할당된 메모리를 주로 NULL로 초기화하는 경우에 많이 이용된다. (NULL로 초기화를 하느냐 안하느냐에 따라 차이가 있다.)

  • 함수 이름 | 기능
  • memset | 메모리 영역을 초기화한다.

memset을 이용한 예시는 아래와 같다.