-
[42SEOUL] Libft : Part 142SEOUL 2021. 11. 9. 16:12
나만의 C 라이브러리 만들기 : C 표준 라이브러리에 있는 함수들을 직접 구현해보는 과제
[ atoi ]
- 문자열 (char 타입) 을 정수 (int 타입) 로 변환하는 함수
- a - to - i 로 읽을 수 있으며, atof, atol 도 존재함.
기능 및 선언 형태
- nptr 이 가리키는 메모리 영역(시작점)부터, '\0'까지 문자를 읽어들이며 변환한 정수를 반환함. (아래 과정을 순차적으로 진행)
- 처음 공백 문자 (아스키코드 9 ~ 13, 32) 는 뛰어넘음.
- 부호는 하나만 들어올 수 있음.
- 부호를 검사하고 난 후, 연속된 숫자 문자만 읽어들여 정수로 변환함.
#include <stdlib.h> int atoi(const char *nptr); /* 사용 방법 */ atoi("문자"); // 0을 반환 atoi("숫자"); // 숫자를 반환 atoi("숫자 + 문자") // 문자가 나오기 전까지의 숫자를 반환 atoi("문자 + 숫자") // 바로 문자가 나오기 때문에 0을 반환- const char *nptr : (값을 바꾸면 안되는) 문자열의 시작 포인터 (주소)
반환 값
- 성공 시, 변환된 정수 값을 반환함.
- 실패 시, NULL (0) 을 반환함.
더 알아가기
- long long 의 최솟값, 최댓값까지 고려해서 구현해야 함.
- 이 함수는 long long 의 최솟값일 경우 0 을 리턴하며, 최댓값일 경우에는 -1 을 리턴함.
- 계산하는 과정에서 언더플로우와 오버플로우를 방지하기 위해 unsigned long long 을 사용했으며, 미리 담아둔 sign 의 부호를 이용하여 현재 값이 범위를 벗어났는지 검사하는 방법으로 해결함.
- 정수의 최댓/최솟값을 표현하려면 limits.h 헤더 파일을 사용하는 것이 유용함.
[ bzero ]
- 어떤 메모리의 시작점부터 연속된 범위를 0으로 모두 지정하고 싶을 때 사용하는 함수
기능 및 선언 형태
- s 가 가리키는 메모리 영역(시작점)부터, n 바이트만큼, 0으로 채움.
- s 의 길이보다 n 이 더 클 때, segmentation fault 가 발생함.
#include <strings.h> void bzero(void *s, size_t n); /* 사용 방법 */ bzero('aaaaa', '0'); // 결과 : aaaaa bzero('aaaaa', '3'); // 결과 : 000aa bzero('NULL', '3'); // 결과 : segmentation fault- void *s : 채우고자 하는 메모리의 시작 포인터(주소)
- size_t n : 채우고자 하는 블럭의 크기 (즉 길이, 바이트의 수를 뜻함)
반환 값
- 없음.
더 알아가기
- C 언어 비표준이며 deprecated 된 함수이므로, 사용을 자제하는 게 좋음. 지금은 하위 호환성을 위해 제공되고 있는 함수일 뿐임. (C 언어 표준 함수인 memset 함수 사용을 권장함)
- memset 함수의 두 번째 인자로 0을 입력한 것과 같은 역할을 함.
[ calloc ]
- 특정 크기와 개수에 따라 메모리를 할당하고 0으로 초기화 하는 함수
기능 및 선언 형태
- nmemb * size 만큼의 heap 메모리를 할당하고, 할당된 메모리 주소를 반환함.
- 할당된 메모리 값은 모두 0으로 초기화 함.
#include <stdlib.h> void *calloc(size_t nmemb, size_t size);- size_t nmemb : 할당할 메모리의 개수(길이)
- size_t size : 메모리 하나의 크기
반환 값
- 메모리 할당에 성공 시, 할당된 메모리 주소를 반환함.
- 메모리 할당에 실패 시, NULL을 반환함.
더 알아가기
- 메모리 할당 후 굳이 메모리 값에 대한 초기화가 필요없다면 malloc 을 사용하고, 그렇지 않으면 calloc 을 사용하는 것이 좋음.
[ isalnum ]
- 인수로 받은 문자가 알파벳 또는 숫자인지 검사하는 함수
기능 및 선언 형태
#include <ctype.h> int isalnum(int c)반환 값
- 알파벳 또는 숫자이면, 0이 아닌 값을 반환함.
- 알파벳 또는 숫자가 아니면, 0을 반환함.
[ isalpha ]
- 인수로 받은 문자가 알파벳인지 검사하는 함수
기능 및 선언 형태
#include <ctype.h> int isalpha(int c)반환 값
- 알파벳이면, 0이 아닌 값을 반환함.
- 알파벳이 아니면, 0을 반환함.
[ isascii ]
- 인수로 받은 문자가 ASCII 문자인지 검사하는 함수
기능 및 선언 형태
#include <ctype.h> int isascii(int c)반환 값
- 0에서 127 사이의 아스키코드 값이면, 1을 반환함.
- 0에서 127 사이의 아스키코드 값이 아니면, 0을 반환함.
[ isdigit ]
- 인수로 받은 문자가 숫자인지 검사하는 함수
기능 및 선언 형태
#include <ctype.h> int isdigit(int c)반환 값
- 숫자면, 0이 아닌 값을 반환함.
- 숫자가 아니면, 0을 반환함.
[ isprint ]
- 인수로 받은 문자가 출력할 수 있는 문자인지 검사하는 함수
기능 및 선언 형태
#include <ctype.h> int isprint(int c)반환 값
- 32에서 126 사이의 아스키코드 값이면, 0이 아닌 값을 반환함.
- 32에서 126 사이의 아스키코드 값이 아니면, 0을 반환함.
[ memccpy ]
- 메모리의 값(일부분)을 복사하는 함수로, 복사하던 중 c를 찾으면 복사를 멈춤.
기능 및 선언 형태
- 포인터 src 가 가리키는 곳부터, n 바이트(길이)만큼을, 포인터 dest 가 가리키는 곳에 복사함.
- 복사하면서 c 를 발견하면 복사를 멈추고, 아니면 n 바이트가 다 복사될 때까지 복사를 진행함.
#include <string.h> void *memccpy(void *dest, const void *src, int c, size_t n);- void *dest : 데이터가 복사될 곳의 주소
- const void *src : 복사할 데이터들이 위치한 주소
- int c : src 에서 만나면 복사를 중단할 데이터 ⇒ int 형이지만 내부에서는 unsigned char(1 byte) 로 변환되어서 저장됨.
- size_t n : 복사할 데이터의 바이트 수(크기)
반환 값
- c 를 찾으면 c 의 다음 주소 값을 반환함.
- src 의 값에서 n 만큼 반복했을 때 c 를 찾지 못하면 NULL 값을 반환함.
더 알아가기
- 복사하던 중 메모리 영역이 겹치면 오버랩이 발생하기 때문에 결과 동작은 정의되지 않음.
- dest 나 src 에 NULL 이 오는 경우, segmentation fault 가 발생함.
[ memchr ]
- 특정 문자를 찾아 그 문자의 주소를 반환하는 함수
기능 및 선언 형태
- 포인터 src 가 가리키는 곳부터, n 바이트(길이)만큼을 반복하면서, 처음으로 c 와 일치하는 값의 주소를 반환함.
#include <string.h> void *memchr(const void *s, int c, size_t n);- const void *s : 데이터를 검색할 시작 주소
- int c : 검색을 통해 찾을 값 ⇒ int 형이지만 내부에서는 한 바이트씩 비교하기 때문에 unsigned char(1 byte) 로 변환되어서 사용됨.
- size_t n : 검색할 데이터의 바이트 수(크기)
반환 값
- 일치하는 값이 있다면, 일치하는 값의 주소를 반환함.
- 일치하는 값을 찾지 못한다면, NULL을 반환함.
더 알아가기
- dest 에 NULL 이 오는 경우, segmentation fault 가 발생함.
[ memcmp ]
- 특정 메모리 영역의 내용이 다른 영역과 동일한지 비교하는 함수
기능 및 선언 형태
- 포인터 s1 이 가리키는 처음 n 바이트(길이)의 데이터와, 포인터 s2 가 가리키는 처음 n 바이트(길이)의 데이터가 동일한지 비교함.
#include <string.h> int memcmp(const void *s1, const void *s2, size_t n);- const void *s1 : 메모리 블록을 가리키는 포인터
- const void *s2 : 메모리 블록을 가리키는 포인터
- size_t n : 비교할 데이터의 바이트 수(크기)
반환 값
- 두 메모리 블록이 정확히 같다면, 0을 반환함.
- 두 메모리 블록이 다르다면, s1 이 더 크면 0보다 큰 값을, s2 가 더 크면 0보다 작은 값을 반환함. ⇒ s1 - s2 의 결과를 반환하는 방식으로 구현함.
더 알아가기
- 한 바이트씩 비교하기 때문에 각 포인터는 unsigned char 로 형 변환되어 사용됨.
- s1 이나 s2 에 NULL 이 오는 경우, segmentation fault 가 발생함.
[ memcpy ]
- 메모리의 값(일부분)을 복사하는 함수
기능 및 선언 형태
- 포인터 src 가 가리키는 곳부터, n 바이트(길이)만큼을, 포인터 dest 가 가리키는 곳에 복사함.
#include <string.h> void *memcpy(void *dest, const void *src, size_t n);- void *dest : 데이터가 복사될 곳의 주소
- const void *src : 복사할 데이터들이 위치한 주소
- size_t n : 복사할 데이터의 바이트 수(크기)
반환 값
- 포인터 dest 가 반환됨.
더 알아가기
- 여기서 dest 와 src 의 타입은 함수와 무관함. 왜냐하면 이 함수는 단순히 이진 데이터를 복사하는 것이기 때문임.
- 이 함수는 src 의 널 문자를 검사하지 않음. 언제나 정확히 n 바이트만큼을 복사함. ⇒ '\0'을 만났다고 해서 멈추지 않음! 그렇기 때문에 전체를 복사할 때는 문자열의 끝을 알리는 '\0'의 길이도 계산해서 넣어주어야 함. (+1 길이)
- 이 함수는 src 메모리 블록과 dest 메모리 블록이 겹쳐져 있는 곳에서는 오버랩이 발생하기 때문에 사용하지 못함. 만약, 동일한 메모리 공간에 덮어씌워야 한다면 memmove 함수를 사용해야 함. (오버랩이란? src 의 원본 값이 이전 src 로 바뀐 상태에서 복사되는 현상) ⇒ 하지만, 요즘에는 둘 다 동일하게 작동하긴 함.
- dest 나 src 가 NULL 이고 n 이 0이 아닌 경우, segmentation fault 가 발생함.
[ memmove ]
- 메모리의 값(일부분)을 복사하는 함수 (memcpy 와 같은 기능이지만 보다 안전성이 높음)
기능 및 선언 형태
- 포인터 src 가 가리키는 곳부터, n 바이트(길이)만큼을, 포인터 dest 가 가리키는 곳에 복사함.
- 메모리 복사 수행 시, 중간에 버퍼를 이용하게 되므로 dest 와 src 의 범위가 겹쳐져도 문제되지 않음.
#include <string.h> void *memmove(void *dest, const void *src, size_t n);- void *dest : 데이터가 복사될 곳의 주소
- const void *src : 복사할 데이터들이 위치한 주소
- size_t n : 복사할 데이터의 바이트 수(크기)
반환 값
- 포인터 dest 가 반환됨.
더 알아가기
- src 시작 주소가 dest 시작 주소보다 앞에 있을 때, 오버랩의 가능성이 생김. ⇒ 이 함수는 dest와 src의 메모리 영역이 겹칠 때, 겹치지 않는 메모리 영역부터 먼저 복사하기 때문에 문제되지 않음. ⇒ src 보다 dest 가 큰 경우, 뒤에서부터 한 바이트씩 복사함.
- dest 나 src 가 NULL 이고 n 이 0이 아닌 경우, segmentation fault 가 발생함.
[ memset ]
- 어떤 메모리의 시작점부터 연속된 범위를 특정 값으로 (바이트 단위) 모두 지정하고 싶을 때 사용하는 함수
기능 및 선언 형태
- s 가 가리키는 메모리 영역(시작점)부터, n 바이트만큼, 지정한 값인 c 로 채움.
#include <string.h> // 또는 memory.h void *memset(void *s, int c, size_t n);- void *s : 채우고자 하는 메모리의 시작 포인터(주소)
- int c : 메모리에 채우고자 하는 값 ⇒ int 형이지만 내부에서는 unsigned char(1 byte) 로 변환되어서 저장됨.
- size_t n : 채우고자 하는 블럭의 크기 (즉 길이, 바이트의 수를 뜻함)
반환 값
- 성공 시, 메모리 영역에 대한 첫 번째 인자를 가리키는 포인터 s 를 반환함.
- 실패 시, NULL 을 반환함.
더 알아가기
- 메모리의 내용을 모두 0으로 초기화할 때 주로 사용함.
- 대체로 memset 함수는 특정 범위에 있는 연속된 메모리 값을 지정하고 싶을 때 사용하는데 컴파일러 또는 컴퓨터 아키텍처에 따라 for 문보다 더 빠른 속도가 나올 수도 있음.
- s 가 NULL 인 경우, segmentation fault 가 발생함.
- c 가 정수형 타입의 범위를 넘어선 경우 compile error 가 발생함.
[ strchr ]
- 문자열에서 특정 문자가 가장 먼저 나타나는 곳의 위치를 찾아 주소를 반환하는 함수
기능 및 선언 형태
- 포인터 s 가 가리키는 곳부터 '\0'까지 반복하면서, 처음으로 c 와 일치하는 값의 주소를 반환함.
#include <string.h> char *strchr(const char *s, int c);- const char *s : 문자열의 시작 주소
- int c : 검색할 문자 ⇒ int 형태로 형 변환 되어서 전달되지만, 함수 내부적으로 다시 char 로 변환되어서 사용됨.
반환 값
- 검색할 문자가 있다면, 가장 먼저 나타나는 곳을 가리키는 포인터를 반환함.
- 문자가 없다면, NULL 을 반환함.
더 알아가기
- s 가 NULL 인 경우, segmentation fault 가 발생함.
[ strdup ]
- 문자열의 길이 + 1 의 크기를 malloc 으로 할당 후, 문자열을 복사해 반환하는 함수
기능 및 선언 형태
- 문자열 s 의 길이에 1을 더한 크기를 malloc 으로 할당하고, 문자열 s 를 복사한 후 반환함.
- (1을 더한 공간인) 마지막에는 '\0' 문자를 넣어줌.
#include <string.h> char *strdup(const char *s);- const char *s : 복사할 문자열
반환 값
- 성공적으로 복사했다면, 복사한 문자열을 반환함.
- 복사에 실패했다면, NULL 을 반환함.
더 알아가기
- malloc 으로 할당한 데이터를 반환하므로, 반환받은 메모리는 사용이 끝난 후 반드시 free 를 통해 메모리를 해제해야 함.
- s 가 NULL 인 경우, segmentation fault 가 발생함.
[ strlcat ]
- 어떤 문자열 뒤에 특정 문자열을 복사하여 붙이는 함수
기능 및 선언 형태
- 문자열 dest 의 끝 ('\0') 부터 최대 size - strlen(src) - 1 만큼의 src 를 복사하며, 마지막에 널 문자를 넣어줌.
- size 는 대상 버퍼의 크기를 의미하며, strlen(dest) + strlen(src) + 1 로 이루어짐. (1은 널 문자를 의미)
#include <string.h> size_t strlcat(char *dest, const char *src, size_t size)- char *dest : 복사될 문자열의 시작 주소
- const char *src : 복사할 문자열의 시작 주소
- size_t n : 복사할 데이터의 바이트 수(크기)
반환 값
- dest 의 길이가 size 보다 크거나 같은 경우, size + src 길이를 반환함.
- dest 의 길이가 size 보다 작은 경우, dest + src 길이를 반환함. (NULL 값을 제외한 길이)
더 알아가기
- strlcat, strlcpy 함수는 보안 목적을 위해 만들어진 함수임. 실수하지 않도록 안전하고 오류발생률을 낮춰 철저히 디자인 되었음. 또한 둘 다 NULL 종료가 되도록 보증함.
- src 와 dest 문자열이 겹치는 경우 동작이 정의되지 않음. (NULL 반환)
- dest 나 src 가 NULL 인 경우, segmentation fault 가 발생함.
[ strlcpy ]
- 어떤 문자열을 특정 문자열로 복사하는 함수
기능 및 선언 형태
- 문자열 dest 에 src 를 복사하며, size 에 따라 복사 길이가 정해짐.
- size 는 문자열 끝의 NULL 까지 포함한 길이임.
- size 가 0이 아닌 경우 size - 1 만큼의 문자를 dest 에 src 를 복사한 후, NULL (0) 을 넣어주고 종료됨.
#include <string.h> size_t strlcpy(char *dest, const char *src, size_t size)- char *dest : 복사될 문자열의 시작 주소
- const char *src : 복사할 문자열의 시작 주소
- size_t n : 복사할 데이터의 바이트 수(크기)
반환 값
- src 의 총 길이를 반환함.
더 알아가기
- strlcat, strlcpy 함수는 보안 목적을 위해 만들어진 함수임. 실수하지 않도록 안전하고 오류발생률을 낮춰 철저히 디자인 되었음.
- 기존의 strncpy 에서는 src 의 길이가 dest 의 길이와 같거나 더 길 경우, 끝에 NULL 이 들어가지 않음. 하지만 strlcpy 에서는 마지막에 반드시 NULL 종료가 되도록 보증함.
- src 와 dest 문자열이 겹치는 경우 동작이 정의되지 않음. (NULL 반환)
- dest 나 src 가 NULL 인 경우, 0 을 반환함.
[ strlen ]
- 문자열의 길이를 반환하는 함수
기능 및 선언 형태
#include <string.h> size_t strlen(const char *s)- const char *s : 검사할 문자열의 시작 주소
반환 값
- s 의 길이를 반환함.
더 알아가기
- s 가 NULL 일 경우, segmentation fault 가 발생함.
[ strncmp ]
- 두 문자열의 일부 문자들을 비교하는 함수
기능 및 선언 형태
- 문자열 s1 의 처음 n 개의 문자를, 다른 문자열 s2 의 처음 n 개의 문자와 비교함.
#include <string.h> int strncmp(const char *s1, const char *s2, size_t n);- const char *s1 : 문자열의 시작 주소
- const char *s2 : 문자열의 시작 주소
- size_t n : 비교할 데이터의 바이트 수(크기)
반환 값
- n 개의 문자가 모두 일치한다면, 0을 반환함.
- 일치하지 않는다면, 최초로 일치하지 않는 문자의 값이 s1 이 더 큰 경우 0보다 큰 값을 반환하고, s2 가 더 큰 경우 0보다 작은 값을 반환함. ⇒ s1 이 s2 보다 클 때 1 반환, 아니면 -1 반환하는 방식으로 구현함.
[ strnstr ]
- 문자열 안에 특정 문자열이 있는지 탐색하는 함수
기능 및 선언 형태
- 포인터 s1 이 가리키는 곳부터 size 의 길이만큼 반복하면서, 문자열 s2 가 있는지 탐색함.
#include <string.h> void *strnstr(const char *s1, const char *s2, size_t size);- const char *s1 : 탐색할 문자열의 시작 포인터(주소)
- const char *s2 : 찾을 문자열의 시작 포인터(주소)
- size_t size : 탐색할 데이터의 바이트 수(크기)
반환 값
- 찾을 문자열 s2 가 없으면, 문자열 s1 를 그대로 반환함. (이 때, 포인터로 접근하기 때문에 빈 문자열이 아닌 NULL이 들어가 있으면 segmentation 발생)
- s2 를 찾으면, 문자열 s1 에서 s2 가 시작되는 위치의 주소를 반환함.
- s1 문자열에서 s2 를 찾지 못하면, NULL 을 반환함.
[ strrchr ]
- 문자열에서 특정 문자가 가장 마지막으로 나타나는 곳의 위치를 찾아 주소를 반환하는 함수
기능 및 선언 형태
- 포인터 s 가 가리키는 곳부터 '\0'까지 반복하면서, 마지막으로 c 와 일치하는 값의 주소를 반환함.
#include <string.h> char *strrchr(const char *s, int c);- const char *s : 문자열의 시작 주소
- int c : 검색할 문자 ⇒ int 형태로 형 변환 되어서 전달되지만, 함수 내부적으로 다시 char 로 변환되어서 사용됨.
반환 값
- 검색할 문자가 있다면, 가장 마지막으로 나타나는 곳을 가리키는 포인터를 반환함.
- 문자가 없다면, NULL을 반환함.
더 알아가기
- s 가 NULL 인 경우, segmentation fault 가 발생함.
[ tolower ]
- 인수로 받은 문자가 대문자일 때 소문자로 변환해주는 함수
기능 및 선언 형태
#include <ctype.h> char tolower(int c);반환 값
- 들어오는 값이 대문자이면, 소문자로 변환한 값을 반환함.
- 들어오는 값이 대문자가 아니면, 그대로 반환함.
[ toupper ]
- 인수로 받은 문자가 소문자일 때 대문자로 변환해주는 함수
기능 및 선언 형태
#include <ctype.h> char toupper(int c);반환 값
- 들어오는 값이 소문자이면, 대문자로 변환한 값을 반환함.
- 들어오는 값이 소문자가 아니면, 그대로 반환함.
더보기[출처/인용]
- https://dojang.io/mod/page/view.php?id=34
- https://www.notion.so/bzero-a14c0b7d420b48c98ad6b0649dd83a6e
- https://www.it-note.kr/51?category=1067589
- https://whatdocumentary.tistory.com/36
- http://neosrtos.com/docs/posix_api/string_memccpy.html
- https://www.it-note.kr/66 https://gawoori.net/memccpy-3-리눅스-매뉴얼-페이지/
- https://riptutorial.com/ko/c/example/2150/겹치는-메모리-복사하기
- https://modoocode.com/92
- https://modoocode.com/84
- https://modoocode.com/77
- https://blockdmask.tistory.com/442
- https://modoocode.com/78
- https://twpower.github.io/79-usage-of-memset-function
- https://blockdmask.tistory.com/441
- https://www.quora.com/What-makes-memset-so-fast
- https://stackoverflow.com/questions/7367677/is-memset-more-efficient-than-for-loop-in-c
- https://modoocode.com/93
- https://www.it-note.kr/78
- https://velog.io/@mjung/function-strlcpy-strlcat
- https://hanul-dev.netlify.app/c/strlcat()-구현/
- https://whatdocumentary.tistory.com/45
- https://m.blog.naver.com/PostView.nhn?blogId=01191879872&logNo=221111654384&proxyReferer=https:%2F%2Fwww.google.com%2F
- https://velog.io/@mjung/function-strlcpy-strlcat
- https://blog.dasomoli.org/478/
- https://whatdocumentary.tistory.com/44
- https://modoocode.com/90
- https://whatdocumentary.tistory.com/49
'42SEOUL' 카테고리의 다른 글
[42SEOUL] Netwhat : 넷마스크와 서브넷 마스크, 서브넷팅 (Netmask, Subnet mask, Subnetting) (0) 2021.11.09 [42SEOUL] Netwhat : 공인 IP와 사설 IP (Public/Private IP Address) (0) 2021.11.09 [42SEOUL] Netwhat : IP Address 란? (0) 2021.11.09 [42SEOUL] Libft: Bonus (0) 2021.11.09 [42SEOUL] Libft: Part 2 (0) 2021.11.09