Skip to content

Instantly share code, notes, and snippets.

@Taehun
Created November 11, 2011 23:56
Show Gist options
  • Save Taehun/1359720 to your computer and use it in GitHub Desktop.
Save Taehun/1359720 to your computer and use it in GitHub Desktop.
연결 리스트 예제
#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;
}
@Taehun
Copy link
Author

Taehun commented Nov 18, 2011

char *로 캐스팅 하는 이유는 바이트 단위로 포인터 연산을 하기 위함입니다. 예를 들어, int형 포인터에서 -1을 빼면 실제 포인터(주소)는 4가 감소하게 됩니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment