[42 Seoul 성장기] Libft

EOH·2023년 4월 26일
0

42Seoul 성장기

목록 보기
1/5
post-thumbnail

✏️ 과제 요약

일단 묻지도 따지지도 말고 함수를 왕창 구현한다. 이 함수들을 묶어 정적라이브러리로 링크한다. 나만의 라이브러리 완성! 참 쉽죠?

🗺️ 과제 해결 로드맵


🔑 공부한 key word

  • 함수구현과 예외처리
  • 헤더파일, 라이브러리, 메이크파일
  • 연결 리스트(bonus과제)

🌋 고비와 극복 방법

고비 1️⃣ : null값과 null포인터는 다르다?

구현해야하는 함수 중 ft_strtrim이라는 함수를 구현할 때 null값과 null포인터의 차이에 대해 알게 되었다.

char *ft_strtrim(char const *s1, char const *set)

프로토타입은 위와 같다. 이 함수는 s1의 앞 뒤에서 연속된 set들을 잘라내는 함수이다. 예를 들어 s1 = abcdefbca 이고 set = ab이면 cdefbc만 남는 것이다.
이 함수의 예외사항은 s1이 모두 set으로 이루어져있을 때이다. 처음에는 이 때 null값을 반환하도록 하였다.
그런데 테스터기를 통과하지 못해 동료에게 물어보니 null값이 아니라 null포인터를 반환해야한다고 했다.
null값이랑 null포인터는 어떻게 다른 것일까?
null값은 값이 null이라는 뜻이고 null포인터는 null을 가르키는 포인터라는 뜻이다. 그러니까 null 포인터는 주소값이 할당은 되어있고 주소값이 가르키는 값이 null인 경우를 의미한다.
말로만 쓰니까 말장난 같은데 간단하게 테스트를 해보면 이해가 더 쉬울 것이다.

#include <stdlib.h>
#include <stdio.h>

int main()
{
	char	*result;
	
    result = (void *)malloc(sizeof(void) * 0);

	if (result == NULL)
		printf("result == 0");
	if (*result == 0)
		printf("*result == 0");

	return (0)
}

위 코드를 실행하면 아래와 같은 결과가 나온다.

할당은 되어 주소를 가리키고있고 그 값이 null인 변수가 어떤 것인지 볼 수 있다.
최종 코드는 아래와 같다. 나는 과제에서 만들어 놓은 ft_strdup함수(들어온 인자와 똑같은 값을 가진 char *을 할당하여 반환하는 함수)에 ""(NULL)을 인자로 넘겨주어 ft_strtrim을 완성했다.

char	*ft_strtrim(char const *s1, char const *set)
{
	size_t	start;
	size_t	end;
	size_t	i;
	char	*result;

	i = 0;
	start = 0;
	end = ft_strlen(s1) - 1;
	while (ft_strchr(set, s1[start]) && s1[start])
		start++;
	while (ft_strchr(set, s1[end]) && end > 0)
		end--;
	if (start == ft_strlen(s1))
		return (ft_strdup(""));
	result = (char *)malloc(sizeof(char) * (end - start + 2));
	if (!result)
		return (0);
	while (start + i <= end)
	{
		result[i] = s1[start + i];
		i++;
	}
	result[i] = '\0';
	return (result);
}

고비 2️⃣ : 연결 리스트

보너스 과제는 연결리스트에 관한 함수들이었다. 일단 리스트를 처음 사용해보아서 이게 어떤건지부터 알아봐야했다.
연결리스트는 구조체를 이용한 자료구조로 같은 타입의 구조체들이 이어져있는 것을 연결리스트라고 한다.

typedef struct s_list
{
	struct s_list	*next;
    void			*content;
}	t_list;

이번 과제에 쓴 연결리스트에 이용할 노드를 나는 이렇게 정의했다.
노드에 실제로 담길 내용과 다음에 연결될 노드의 주소를 가지고 있는 단순한 노드이다.
이런 노드들이 모여서 하나의 리스트가 되는 것이다. 이번 과제에서는 리스트가 노드가 이어져있는 구조라는 것만 이해하면 수행할 수 있었다.

고비 3️⃣ : 새로운 헤더파일 만들기

c언어를 처음 공부할 때 #include <stdio.h>를 써보면서 이 헤더파일이라는 것은 어떻게 만들지?라는 궁금증이 있었는데 42서울 첫 과제에서 바로 해보게 되었다.

❓ 헤더파일이란 무엇이고 왜 필요할까?
컴파일을 할 때 다른 한 함수에서 다른 함수를 불러와 사용했으면 이 함수들의 원형을 제일 상단에 적어주어야 컴파일이 가능하다.
함수를 한두개만 사용해도 일일히 적어주기에는 번거로운데 많은 함수를 사용했다면 더 헷갈리고 힘들것이다. 이를 해결해주는 것이 헤더파일이다.
libft의 헤더파일 libft.h의 일부를 예로 들어보자.

#ifndef LIBFT_H
# define LIBFT_H

# include <stdlib.h>
# include <unistd.h>

typedef struct s_list
{
	void			*content;
	struct s_list	*next;
}	t_list;

int			ft_isalpha(int c);
int			ft_isdigit(int c);
int			ft_isalnum(int c);
int			ft_isascii(int c);
int			ft_isprint(int c);
size_t		ft_strlen(const char *s);
void		*ft_memset(void *s, int c, size_t n);
void		ft_bzero(void *s, size_t n);
.
.
.
#endif

헤더파일은 #ifndef와 #endif로 전체를 감싸야한다.
전체적인 구성은

#ifndef LIBFT_H (libft.h가 정의되어있지않다면)
#define LIBFT_H (libft.h를 아래의 내용들로 정의한다)
... (내용들)
#endif (정의가 끝났다)

이렇게 되며 사이에 우리가 정의하고 싶은 내용을 넣으면 된다. 나는 보너스에서 연결리스트 구현에 사용한 구조체와 컴파일러에게 넘겨주고 싶은 함수들을 모두 적었다.

이제 헤더파일을 만들었으니 이 헤더파일 안에 있는 함수나 구조체를 사용하고 싶다면 파일 제일 위에
#include "libft.h" 를 하면 된다.

TIP) 사용자정의 라이브러리는 #include "..." 형식을 따른다

고비 4️⃣ : 라이브러리로 만들기

헤더파일이 있으면 다 된것 같지만 그렇지 않다. 라이브러리로 묶어서 하나의 정적라이브러리로 만들어줘야 사용할 수 있다.
정적라이브러리란 프로그램 빌드 시 라이브러리가 제공하는 코드를 실행파일에 넣는 방식의 라이브러리를 의미한다.

❓라이브러리와 헤더파일은 뭐가 다를까?
라이브러리는 실제로 기계어로 번역되어 컴퓨터가 사용할 수 있게 만든 파일이고, 헤더는 사람들이 알아들을 수 있게 선언된 참조의 영역이다.
라이브러리로 만들려면 우리가 적어준 모든 소스코드를 libft.a라는 파일로 묶어서 라이브러리를 만들어야 한다.
실행파일을 만들 때 gcc를 하듯 라이브러리(*.a)를 만들 때는 ar -cr이라는 명령어를 사용해주어야한다.
ar -cr libft.a ft_isalpha ft_isdigit ... 을 해주면 libft.a라는 라이브러리가 생성이 된다.

❗️ 느낀 점

나 빼고 모두 전공자였던 스터디 팀원 사이에서 진도는 가장 느렸지만 느린만큼 꼼꼼하게 공부했고 팀원들에게 배우는 것도 많았다. 라피신 마지막 날까지 어려웠던 ft_split함수를 이제 스스로 작성할 수 있다니. 내 자신 아주 칭찬해
함수를 많이 만들어보면서 예외처리사항을 많이 다루다보니 확장해서 여러 케이스를 고려하고 함수를 짜는 능력이 키워졌다. makefile, header file, library 등 코드를 실행시키는 방법도 배웠고 컴퓨터가 컴파일하는 방식에 대해서도 알게 되었다.
이번 과제로 알고리즘 + CS에 대한 지식이 많이 향상된 것 같다.

📚 소스코드 & 스터디 노션페이지

스터디 노션페이지
Github
스터디 노트 및 소스코드는 노션과 깃허브에서 볼 수 있습니다.

profile
에-오

0개의 댓글