학습 날짜
•
2020/12/21(월)
학습 시간
•
09:00 ~ 22:00 (자가)
학습 범위 및 주제
•
Libft
•
code convention(with c)
동료 학습 방법
•
온라인(google meets를 활용) 스터디 진행
•
본인 포함 4명 (@jseo @chan @hyson)
학습 목표
•
c 기초 라이브러리 공부 & c style coding 배우기
상세 학습 내용
Libft
•
memset
1.
함수 원형
//c header
#include <string.h>
void* memset(void* dest, int value, size_t size);
Plain Text
복사
2.
함수 설명
•
dest 의 주소부터 size 바이트를 value 값으로 채운다.
•
이 때, value 는 unsigned char 로 형변환된다.
→ 따라서 int값으로 초기화는 불가능하다!
int main(void)
{
int memset_with_0[5];
int memset_with_1[5];
memset(memset_with_0, 0, sizeof(memset_with_0));
memset(memset_with_1, 1, sizeof(memset_with_1));
//memset_with_0 출력
printf("memset_with_0 : ");
for (int i = 0; i < 5; i++)
printf("%d ", *(memset_with_0 + i));
//memset_with_1 출력
printf("\\nmemset_with_1 : ");
for (int i = 0; i < 5; i++)
printf("%d ", *(memset_with_1 + i));
return 0;
}
Plain Text
복사
위와 같이 두 배열을 0과 1로 초기화 한다면
0 0 0 0 0
16843009 16843009 16843009 16843009 16843009
Plain Text
복사
위와 같이 출력이 된다.
결과에서 보이듯이 1로 초기화 하고 싶었지만 기대한 결과값이 나오지 않는다!
이유는 memset 함수는 1바이트 단위로 값을 초기화 하기 때문이다!
따라서 모든 값을 0으로 초기화하거나 char값으로 초기화 할 때 사용하면 된다.
◦
* memset의 char형의 배열에 대한 초기화는 어떤 값을 넣어도 무방하다. 다만 memset 초기화의 대상이 int일 때만 문제가 된다! 아래에서 제시할 것들은 int형 배열에 대한 초기화를 기준으로 제시한 것이다.
◦
* memset으로 올바르게 형변환 되어 이용할 수 있는 수는 0과 -1이다. 0은 1 Byte기준 2진수로 $00000000$이고, 4 Byte로는 $00000000000000000000000000000000$이다. 1Byte 단위로 읽어도 어차피 0으로 초기화 될 수 밖에 없다. -1은 1 Byte 기준 2진수로 $11111111$이고, 4 Byte로는 $11111111111111111111111111111111$이다. 이 역시 어차피 -1로 해석이 될 수 밖에 없는 구조를 띈다.
◦
* 그렇다면 위의 예제에서 int 배열을 1로 초기화 하려고 했을 때 왜 1이 되지 않는지 살펴보자. memset은 1 Byte 단위로 초기화 시킨다. 그럴 때 4 Byte 크기를 갖는 int 데이터 하나는 $0000001 00000001 00000001 00000001$ 과 같은 형태를 띄게 된다.
2진수로 표현된 값을 확인해보면 위의 그림과 같이 $16483009$의 값을 가진채로 int 배열이 초기화 되는 것이다. 이를 염두해 두고 memset은 바이트 단위의 초기화를 수행하기 때문에 char 형태의 배열에 용의한 것이고, 따라서 string.h에 들어있는 함수인 것도 이 이유 때문임을 유추할 수 있다.
•
bzero
1.
함수 원형
//c header
#include <string.h>
void bzero(void* dest, size_t size);
Plain Text
복사
2.
3.
Return Value
없음
•
memcpy
1.
함수 원형
//c header
#include <string.h>
void* memcpy(void* dest, const void* src, size_t size);
Plain Text
복사
2.
함수 설명
•
src가 가리키는 곳 부터 size바이트만큼 dest에 복사한다.
3.
Return Value
•
dest 를 리턴한다.
•
memccpy
1.
함수 원형
//c header
#include <string.h>
void* memccpy(void* dest, const void* src, int ch, size_t size);
Plain Text
복사
2.
함수 설명
•
src 가 가리키는 곳 부터 size 바이트만큼 dest에 복사한다.
•
만약 src에서 문자 ch를 만나면 ch까지만 복사를 진행하고 복제를 중단한다.
3.
Return Value
•
복사된 dest변수에서 복사가 끝난 다음 주소를 리턴한다.
•
만약 문자 ch를 만나지 않았다면, size 바이트를 복사하고 NULL을 리턴한다.
•
memmove
1.
함수 원형
//c header
#include <string.h>
void* memmove(void* dest, const void* src, size_t size);
Plain Text
복사
2.
함수 설명
•
src 가 가리키는 곳 부터 size 바이트 만큼 dest 가 가리키는 곳으로 옮긴다.
•
버퍼를 이용하므로 dest 와 src 가 겹쳐도 문제 없다.
3.
Return Value
•
dest 를 리턴한다.
•
memchr
1.
함수 원형
//c header
#include <string.h>
void* memchr(const void* dest, int ch, size_t size);
Plain Text
복사
2.
함수 설명
•
dest 가 가리키는 곳 부터 size 바이트 까지 중 처음으로 ch 와 일치하는 값을 찾는다.
•
ch는 unsigned char로 해석된다.
3.
Return Value
•
문자 ch 를 만났다면 해당 주소를 리턴한다.
•
만약 문자 ch를 만나지 않았다면, size 바이트를 복사하고 NULL을 리턴한다.
•
memcmp
1.
함수 원형
//c header
#include <string.h>
int memcmp(const void* ptr1, const void* ptr2, size_t size);
Plain Text
복사
2.
함수 설명
•
두 메모리 블록을 비교한다.
•
ptr1이 가리키는 size바이트의 데이터와 ptr2가 가리키는 size바이트의 데이터를 비교한다.
3.
Return Value
•
두 메모리 블록이 같으면 0을 리턴한다.
•
두 메모리 블록이 다른 곳에서 ptr1의 값이 더 크면 0 보다 큰 값을 리턴한다.
•
두 메모리 블록이 다른 곳에서 ptr2의 값이 더 크면 0 보다 작은 값을 리턴한다.
→ 두 메모리 블록이 같지 않다면 *ptr1 - *ptr2 값을 리턴한다.
•
strlen
1.
함수 원형
//c header
#include <string.h>
size_t strlen(const char* str);
Plain Text
복사
2.
함수 설명
•
문자열 str의 길이를 구한다
•
간혹 아래와 같이 선언되어 있다면
char str[100] = "Hello World!";
Plain Text
복사
100을 리턴하지 않고 12를 리턴하게 된다.
strlen 함수는 문자열의 마지막 NULL 문자에 의해 길이를 결정하기 때문이다!
3.
Return Value
•
문자열의 길이(부호없는 정수형)을 리턴한다.
•
strlcpy
1.
함수 원형
//c header
#include <string.h>
size_t fstrlcpy(char* dest, const char* src, size_t size);
Plain Text
복사
2.
함수 설명
•
작동원리는 strncpy와 비슷하지만 strncpy함수보다 오류가 적은 함수이다.
•
strncpy의 경우 NULL문자 삽입을 보장하지 않는다.
•
strlcpy는 size가 0이 아닌 경우 size - 1 까지 복사를 진행하고 마지막에 NULL을 삽입해준다.
s
3.
Return Value
•
src의 길이를 리턴한다.
학습 내용에 대한 개인적인 총평
처음에 과제를 직면했을 때, 영어로 만들어진 subject에다가 라이브러리를 한보따리 만들어야해서 엄청 당황을 했었고, 오프라인으로 클러스터에서 진행되는 것이 아니라 온라인으로 하다보니 많이 막막했었다. 하지만 구글 meets를 활용해 피씬과정을 함께한 동료들과 같이 차근차근 진행하니 생각보다 부담스러운 문제들은 아니였던 것 같다. 확실히 동료학습의 중요성을 많이 느끼고 온라인으로 하는 것도 큰 효과가 있는데 오프라인에서 진행하면 더 엄청난 시너지가 나올 것 같다.
피신 기간이 끝난 후 c++알고리즘 스터디를 진행하면서 대부분 알아두었던 라이브러리가 종종 나와서 첫 라이브러리에 대한 공부를 하고 나니 뒤에 나오는 것들도 어려움 없이 넘어갈 수 있었다. 고급 언어들을 사용하면서 대부분 라이브러리를 사용하기만 하였지 라이브러리를 직접 짜본적은 많이 없었는데 이번 기회를 통해서 함수 내부의 구조에 대해서도 자세히 알게될 것 같고 무심결에 썼던 함수들도 특징을 꼼꼼하게 알고 갈 수 있을 것 같다.
첫 과제라서 부담이 있었지만, 경쟁하는 분위기가 아니라 같이 함께 성장하는 분위기여서 힘을 낼 수 있었다.
다음 학습 계획
strlcpy 다음 라이브러리부터 part1 라이브러리에 대한 전반적인 이해를 끝내고 위에서 공부한 내용을 토대로 코드에 녹여볼 예정이다. 기존 라이브러리에 있던 함수와 비교해 가면서 코드가 정확하게 작동하는지 확인한 후 예외 케이스가 있는지 살펴볼 예정이다.