ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [42SEOUL] Libft : Part 1
    42SEOUL 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);

    반환 값

    • 들어오는 값이 소문자이면, 대문자로 변환한 값을 반환함.
    • 들어오는 값이 소문자가 아니면, 그대로 반환함.

    더보기

    댓글

leejiwonn