[bonus] ft_lstnew & Linked List

[bonus] ft_lstnew & Linked List

“ft_lstnew에 대하여”

<목차>

1. MY CODES

2. 연결 리스트

3. ft_lstnew

ft_lstnew – 새로운 연결 리스트를 할당하여 반환한다.

(1) MY CODES

#include "libft.h"

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

t_list	*ft_lstnew(void	*content)
{
	t_list	*new;

	new = (t_list *)malloc(sizeof(t_list));
	if (new == NULL)
		return (NULL);
	new->content = content;
	new->next = NULL;
	return (new);
}

(2) 연결 리스트

  • libft의 bonus에서는 연결 리스트를 작성하게 된다. 피신을 준비하면서 처음 프로그래밍을 시작했던 나에게는 매우 생소한 개념이었는데, 그래서 통과 위주로 코드를 작성했던 기억이 난다. 하지만 연결 리스트도 과제를 하면서 계속계속 사용할 일이 생기기 때문에 가능하다면 잘 이해해두고 넘어가는 것이 좋다. 과제를 진행하면서 연결 리스트 개념을 완성시켜보자.

1. 배열에 복수의 data를 탑재할 수 있다면 어떨까?

  • 일반적으로 선언되는 배열들(char, int, float* …)은 한번에 하나의 요소들만 다룰 수가 있다. 만약 struct연결 리스트에 대한 지식이 없다면 두 가지 이상의 자료형을 다루기 위해서는 두 개 이상의 배열을 선언해야 할 것이다. 예를 들어 학생의 번호와 이름을 다루고자 한다면…
int*	number = 3; // 학생 3명
char**	name = (char**)malloc(sizeof(char*) * (number)); // 학생의 이름을 담을 이중 배열
  • 정말로 끔찍한 일이 아닐 수가 없다. 내가 연결 리스트를 아무리 어려워했어도 학번과 이름을 다루기 위해 배열을 2개 쓰는 짓은 하지 않았을 것이다.

2. C struct

  • 배열에 복수의 data를 탑재할 수 있는 방법이 있다. 그것은 바로 구조체(structure type)를 이용하는 것이다. 구조체란, 사용자가 C언어의 기본 타입을 가지고 새롭게 정의할 수 있는 사용자 정의 타입이다. 구조체는 기본 타입만으로는 나타낼 수 없는 복잡한 데이터를 표현할 수 있다. 위에서 학번과 학생의 이름을 저장하고자 했었는데, struct를 통해 작업해보자.
typedef struct student
{
	int			num;
	char		*name;	
}	t_student; // 직접 정의한 t_student 구조체 

int main()
{
	t_student	*new_student = (t_student*)malloc(sizeof(t_student));
	new_student->num = 1;
	new_student->name = "gyopark";

	printf("name : %s, number : %d\n", new_student->name, new_student->num);
	return 0;
}
output :
	name : gyopark, number : 1
  • t_student는 내가 직접 정의한 사용자 정의 타입으로, 그 안에 번호와 이름 문자열을 가지고 있다. 이렇게 배열을 2개 쓰지 않고도 2개의 자료형을 다룰 수 있게 되었으며, 원한다면 훨씬 더 많은 자료형을 다룰 수도 있다. 다른 타입들과 마찬가지로 우리는 이 struct의 배열 또한 사용할 수 있다. 이 struct 배열의 사용법이 연결 리스트의 사용법과 맞닿아 있다.

3. t_list

typedef struct	s_list
{
	void			*content;
	struct s_list	*next;
}				t_list;
  • 어떤 방식으로 struct의 배열을 사용할 수 있을까? 과제에서 사용하도록 제시해준 struct를 살펴보자. 위의 t_list는 우리가 libft bonus를 진행하면서 만드는 연결 리스트에서 사용할 구조체로 지정된 것이다. 구조체 안에는 void 포인터 하나와 t_list의 포인터 하나가 존재한다. void 포인터는 어떠한 자료형이든 담을 수 있기 때문에 코드를 작성하면서 원하는 자료형을 담으면 될 것이다. t_list 포인터는 다음 구조체를 가리킨다. 이 t_list 포인터를 통해 struct 배열을 사용할 수 있다. 어떤 구조체의 t_list 포인터가 다음 구조체의 주소를 가리키고, 다음 구조체의 t_list 포인터가 그 다음 구조체의 주소를 가리키고 … 이런 식으로 배열을 구성하게 된다. 마지막 구조체의 t_list 포인터는 NULL을 가리키면서 구조체 배열의 끝을 나타낸다. 그림으로 나타내면 다음과 같다.

linked-list

  • 구조체 배열이 바로 연결 리스트이고, 한 구조체 덩어리를 노드(Node)라고 한다. 일반적으로 첫 번째 노드를 HEAD라 부르고, 마지막 노드를 TAIL이라고 부른다.

(3) ft_lstnew

  • ft_lstnew(void *)는 void 포인터 데이터 하나를 매개 변수로 받아서 그 데이터를 포함하는 노드 하나를 반환한다. 아래 코드를 살펴보자.
#include "libft.h"

t_list	*ft_lstnew(void	*content)
{
	t_list	*new;

	new = (t_list *)malloc(sizeof(t_list));
	if (new == NULL)
		return (NULL);
	new->content = content;
	new->next = NULL;
	return (new);
}

int main()
{
	t_list*		a;

	a = ft_lstnew("gyopark");
	printf("a->content : %s\n", a->content);
	free(a);
	return 0;
}
output :
	a->content : gyopark

ex1-list

  • 위와 같은 노드 하나가 생겼다고 보면 될 것 같다. 이런 식으로 노드를 여러 개 만들어 연결 리스트를 구성할 수 있을 것이다.