Functions
isalpha, isdigit, isascii, isprint
각 인수가 alpha, digit, ascii, printable인지를 체크하는 함수
ASCII코드 번호로 return문 안에서 체크
isalnum
인수가 alpha 또는 digit인지를 체크하는 함수
isalpha, isdigit 활용
strlen
문자열의 길이를 재는 함수
맨 끝 null문자를 제외한 길이
memset
특정 문자열 바이트를 특정 값으로 채우는 함수
void *ft_memset(void *b, int c, size_t len)
- b에서 1바이트씩 옆으로 밀면서 값을 저장해야함. but, 현재 b는 void 포인터이기 때문에 다른 포인터로 변환해야함
The memset() function writes len bytes of value c (converted to an unsigned char) to the string b.
unsigned char
사용하는 이유- 1바이트씩 이동하기 위해, 음수로 인한 에러 방지
- void 포인터
memcpy
메모리의 일부분을 복사하는 함수
- 매개변수
dest
: 채우고자 하는 메모리의 시작 주소src
: 복사하려는 메모리의 시작 주소n
: 채우고자 하는 바이트의 수
- 리턴값
dest
반환
- 구현방법
- 둘다 널이면 널 반환
- memset과 같은 방식으로 채워넣기
if (dst != src)
: dst와 src가 같으면 동작 수행 안되고 바로 리턴됨
memmove
메모리를 이동하는 함수
- memcpy와 비교 (restrict 포인터와 관련?)
- 공통점: 둘다 메모리를 복사함
- 차이점: memcpy-버퍼를 안거치고 바로 복사, memmove-버퍼를 통해 복사 (libft 과제에서는 예외적으로 버퍼개념 대신 위치에 따라 조건을 달리 주는 식으로 구현함.)
→ src 구간에 dst가 있는 경우에 memcpy는 덮어쓴채로 복사되는 문제가 발생하지만 memmove는 그런 문제로부터 자유로움.
- 동작과정
- src → usrc, dst → udst
- 케이스를 dst의 주소가 src의 주소 앞에, 뒤에 있을 때로 나눔& 복사 순서를 앞먼저 or 뒤먼저로 다르게 함.(뒤에 있는 경우 len의 길이에 따라 src의 뒷부분이 잘릴 수 있기 때문에)
strlcpy, strlcat 공통
- restrict 포인터란?
- 각 포인터가 서로 다른 메모리공간을 가르키고 있다는 전제하에 컴파일러가 최적화할 수 있도록 함.
- 앞부분에 널가드 넣지 않은 이유(memcpy와의 차이점)
- C89에서는 유효한 값이 들어온다는 전제가 깔려있기 때문임.(원함수와 같은 동작 위해)
- dstsize : 맨 끝 ‘\0’ 포함된 길이
strlcpy
NULL을 보장하여 문자열을 길이만큼 복사
- 동작과정
- dst에 src를 복사
- 길이 리턴
strlcat
NULL을 보장하여 문자열을 길이만큼 붙임
- 매개변수
char *dst
: 앞 문자열const char *src
: 뒤에 붙일 문자열size_t dstsize
: dst에 src를 덧붙인 총길이(‘\0’포함)
- return 값
- dstsize ≤ dst길이 : src길이 + dstsize
- 그외 : dst길이 + src길이
toupper & tolower
각각 대문자, 소문자로 변환
아스키코드 값으로 각각 32씩 빼고 더해줌.
strchr
문자열의 앞에서부터 특정 문자가 처음 나오는 위치 찾는 함수
while (*s != (char)c)
형변환 이유: c+256이 들어왔을 때 c로 인식해야 하므로 int를 char로 변환해줌.
- 구현방법
- c와 다를때 while문을 돌리다가 널 만나면 리턴. 널 안만나고 while문 끝나면 해당 위치 리턴
strrchr
문자열의 뒤에서부터 특정 문자가 처음 나오는 위치 찾는 함수
strncmp
두 문자열의 일부 문자열을 비교하는 함수
unsinged char
이 쓰이는 이유The comparison is done using unsigned characters, so that ‘\200’ is greater than ‘\0’.
- 위 예시에서 \200은 8진수로 10진수로 변환하면 128이 됨. 따라서 char 자료형이라면 범위인 127을 초과하지만 unsigned char이기 때문에 초과하지 않게 됨.
const char
을 사용한 이유- s1, s2값을 바꾸지 못하게 하기 위함.
memchr
메모리 블록의 일부 범위에서 특정 문자를 찾는 함수
- 구현방법
- void형으로 들어왔기 때문에 unsigned char형으로 형변환
- 해당 범위에서 while문을 돌다가 같은 위치 찾으면 해당 주소값 반환
memcmp
두 개의 메모리 블럭을 n바이트만큼 비교하는 함수
unsigned char *
타입의 다른 변수에 저장해서 비교. (void *
형이기 때문에 명시적 형변환을 거쳐서 사용해야함)
strnstr
특정 문자열에서 len 이하의 범위만큼 문자열을 찾는 함수
- return value
- needle이 빈 경우 → haystack
- haystack에 needle이 없는 경우 → NULL
- 그 외 → needle의 첫번째 발견 지점
- 구현방법
- haystack, needle 둘다 널가드 안넣음→원함수와 같게 seg.fault 일으킴
- len과 nd_len(needle)을 대소비교하며 첫값 비교. (
nd_len <= len-—
: 남은 길이가 needle보다 짧다면?→비교할 필요 없음) - 첫 값이 같다? → memcmp 진행→리턴 or 반복
atoi
문자열 형태로 들어온 인수를 int형으로 반환하는 함수
- return value
- 부호 개수 > 1 or 문자가 맨 처음→ 0
- 숫자+공백 or 공백+숫자 or 숫자+문자 → 앞부분 숫자만
- 구현방법
- 공백체크(스킵)
- 부호체크(1자만) → 피신때와의 차이
- 숫자체크(10씩 자릿수 올려가며)→digit이 아닌값을 만날때까지
- NULL이 입력됐을 때의 경우→ 아무 처리하지 않기.(seg fault 출력)
LONG_MIN
(==2147483647) 선언 헤더 :limits.h
calloc
size
크기의 변수를count
개 저장할 수 있는 메모리 공간 할당 &0
으로 초기화
malloc → 선언헤더 : stdlib.h
- malloc과의 차이점? 1.공간의 값을 0으로 바꾸는지 2.
count
개를 함수 안에서 한번에 할당 가능한지 - malloc(0)에 대해
- NULL과의 차이?
- malloc(0)일때의 동작: gcc에서는 할당을 해줌. 구현체마다 동작이 다름.
count * size > SIZE_MAX
조건을 준 이유- size_t 자료형의 범위를 넘어가는것을 방지하기 위해.
- malloc(SIZE_MAX)→ NULL 리턴될 것. & 원함수와의 동작을 맞춰줌
- SIZE_MAX 선언 헤더 :
limits.h
- 사용예시
1
2
ptr1 = (int*) malloc(sizeof(int) * 5);
ptr2 = (int*) calloc(5, sizeof(int));
strdup
문자열을 새롭게 할당한 메모리 공간에 복사함.
malloc 선언헤더 : stdlib.h
- 구현방법
result
에 메모리 할당 후 널체크 (If insufficient memory is available, NULL is returned and errno is set to ENOMEM.)strlcpy
를 통해 문자열 복사 후 널보장- 복사된 문자열을 리턴.
count + 1
인 이유? strlen은 NULL을 제외한 길이임, strlcpy는 dstsize-1만큼 복사하고 널을 추가하는 함수.
Ref
59.3 void 포인터로 포인터 연산하기
memmove와 memcpy의 차이점
restrict 포인터
널가드 관련 논의
malloc(0)과 NULL의 차이점
calloc 참고문서
limits.h (LONG_MIN, SIZE_MAX 선언)