Created
November 11, 2011 23:56
-
-
Save Taehun/1359720 to your computer and use it in GitHub Desktop.
연결 리스트 예제
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <arch/types.h> | |
/** | |
* @brief 이중 연결 리스트 아이템. | |
*/ | |
struct list_item { | |
struct list_item *prev, *next; | |
}; | |
/** | |
* @brief 리스트 초기화. | |
* @param[in] head 리스트 헤드 아이템. | |
*/ | |
static inline void | |
list_init(struct list_item *head) | |
{ | |
head->next = head; | |
head->prev = head; | |
} | |
/** | |
* @brief 리스트 앞에 새로운 아이템 추가. | |
* @param[in] new 추가 할 아이템. | |
* @param[in] head 리스트 헤드 아이템. | |
*/ | |
static inline void | |
list_add(struct list_item *new, struct list_item *head) | |
{ | |
new->next = head->next; | |
new->prev = head; | |
head->next->prev = new; | |
head->next = new; | |
} | |
/** | |
* @brief 리스트 뒤에 새로운 아이템 추가. | |
* @param[in] new 추가 할 아이템. | |
* @param[in] head 리스트 헤드 아이템. | |
*/ | |
static inline void | |
list_add_tail(struct list_item *new, struct list_item *head) | |
{ | |
new->next = head; | |
new->prev = head->prev; | |
head->prev->next = new; | |
head->prev = new; | |
} | |
/** | |
* @brief 리스트에서 아이템 삭제. | |
* @param[in] item 삭제 할 아이템. | |
*/ | |
static inline void | |
list_del(struct list_item *item) | |
{ | |
item->next->prev = item->prev; | |
item->prev->next = item->next; | |
item->prev = 0; | |
item->next = 0; | |
} | |
/** | |
* @brief 리스트의 앞으로 아이템 이동. | |
* @param[in] item 이동 할 아이템. | |
* @param[in] head 리스트 헤드 아이템. | |
*/ | |
static inline void | |
list_move(struct list_item *item, struct list_item *head) | |
{ | |
item->next->prev = item->prev; | |
item->prev->next = item->next; | |
list_add(item, head); | |
} | |
/** | |
* @brief 리스트의 뒤로 아이템 이동. | |
* @param[in] item 이동 할 아이템. | |
* @param[in] head 리스트 헤드 아이템. | |
*/ | |
static inline void | |
list_move_tail(struct list_item *item, struct list_item *head) | |
{ | |
item->next->prev = item->prev; | |
item->prev->next = item->next; | |
list_add_tail(item, head); | |
} | |
#define offsetof(type, member) ((size_t) &((type *)0)->member) | |
/** | |
* @brief 리스트 아이템을 담고있는 컨테이너를 가져옴. | |
* @param[in] item 컨테이너를 가져올 리스트 아이템 포인터. | |
* @param[in] type 리스트 아이템을 담고 있는 컨테이너 타입. | |
* @param[in] member 컨테이너의 리스트 아이템 멤버이름. | |
*/ | |
#define list_get_entry(item, type, member) \ | |
((type *) ((char *) &(item)->next - offsetof(type, member.next))) | |
/** | |
* @brief 리스트 루프. | |
* @param[in] item 리스트 아이템 포인터. | |
* @param[in] head 헤드 리스트 아이템. | |
*/ | |
#define list_for_each(item, head) \ | |
for (item = (head).next; item != &(head); item = item->next) | |
/** | |
* @brief 리스트 비었는지 여부. | |
* @param[in] head 리스트 아이템 포인터. | |
*/ | |
#define list_empty(head) \ | |
(head == (head)->next) | |
struct sample_data { | |
int a; | |
char b; | |
int c; | |
int d; | |
char e; | |
}__attribute__((packed)); | |
int main(void) | |
{ | |
struct sample_data data; | |
printf("sample_data 구조체의 주소 = %p\n", &data); | |
printf("sample_data 구조체, 멤버 변수 a의 주소 = %p\n", &data.a); | |
printf("sample_data 구조체, 멤버 변수 b의 주소 = %p\n", &data.b); | |
printf("sample_data 구조체, 멤버 변수 c의 주소 = %p\n", &data.c); | |
printf("sample_data 구조체, 멤버 변수 d의 주소 = %p\n", &data.d); | |
printf("sample_data 구조체, 멤버 변수 e의 주소 = %p\n", &data.e); | |
printf("a 멤버 변수의 오프셋 = %d\n", offsetof(struct sample_data, a)); | |
printf("b 멤버 변수의 오프셋 = %d\n", offsetof(struct sample_data, b)); | |
printf("c 멤버 변수의 오프셋 = %d\n", offsetof(struct sample_data, c)); | |
printf("d 멤버 변수의 오프셋 = %d\n", offsetof(struct sample_data, d)); | |
printf("e 멤버 변수의 오프셋 = %d\n", offsetof(struct sample_data, e)); | |
printf("(d 멤버 주소) - (d의 오프셋) = %p\n", (char *)&data.d - offsetof(struct sample_data, d)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
char *로 캐스팅 하는 이유는 바이트 단위로 포인터 연산을 하기 위함입니다. 예를 들어, int형 포인터에서 -1을 빼면 실제 포인터(주소)는 4가 감소하게 됩니다.