contributed by < TingL7
>
生日悖論是指 23 人以上,出現兩個人生日同一天的機率高於 50 %
假設
P(n) : n 人中至少兩人生日是同一天
主要的影響在於 hash function 的應用
hash function 的碰撞,利用窮舉法製作出具有相同 hash value 的檔案或合同,取代真正的檔案以進行欺騙
srand(time(NULL));
,以時間作為亂數種子,使得每次亂數種子都不同,得到不同亂數表,進而得到「亂」數rand()
測試幾次,會發現每次得到的亂數是相同的,因為他的種子每次都相同The basic difference is that function is compiled and macro is preprocessed.
int a;typeof(a) b;
宣告與變數 a
相同 type 的變數 b
#define max(a,b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
#define container_of(ptr, type, member) \
__extension__({ \
const __typeof__(((type *) 0)->member) *__pmember = (ptr); \
(type *) ((char *) __pmember - offsetof(type, member)); \
})
-traditional
、 -ansi
、 -std=c99
會使一些關鍵字失效,如 typeof
,在GNU C 中,在字的前後加上 __
可以解決關鍵字失效的問題container_of(ptr, type, member)
以 __extension__()
取代。const __typeof__(((type *) 0)->member) *__pmember = (ptr);
(type *) 0
: 型態轉成 type * 的 0((type *) 0)->member
: type * 的 0 指向 member
->
可以猜測 type 是 structure__typeof__(((type *) 0)->member)
: type 中 member 的型態
const __typeof__(((type *) 0)->member) *
: 型態為 const type 中 member 的型態 指標const __typeof__(((type *) 0)->member) *__pmember
: 宣告變數__pmember,型態為 const type 中 member 的型態 指標const __typeof__(((type *) 0)->member) *__pmember = (ptr);
: 宣告變數__pmember,型態為 const type 中 member 的型態 指標,指向 ptr 指的位置(type *) ((char *) __pmember - offsetof(type, member));
(char *) __pmember
: 型態轉換成 char * 的 __pmemberoffsetof(type, member)
: type 中 member 的位址大小
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
計算出 struct 和其 member 的距離((char *) __pmember - offsetof(type, member))
: 指向 ptr 也是 struct typr 中的 member的位址 減去 struct 開頭與 member 的距離,也就是 struct 開頭的位址(type *) ((char *) __pmember - offsetof(type, member));
: 以(type *) 儲存 type 開頭的位址
/**
* list_del() - Remove a list node from the list
* @node: pointer to the node
*
* The node is only removed from the list. Neither the memory of the removed
* node nor the memory of the entry containing the node is free'd. The node
* has to be handled like an uninitialized node. Accessing the next or prev
* pointer of the node is not safe.
*
* Unlinked, initialized nodes are also uninitialized after list_del.
*
* LIST_POISONING can be enabled during build-time to provoke an invalid memory
* access when the memory behind the next/prev pointer is used after a list_del.
* This only works on systems which prohibit access to the predefined memory
* addresses.
*/
static inline void list_del(struct list_head *node)
{
struct list_head *next = node->next;
struct list_head *prev = node->prev;
next->prev = prev;
prev->next = next;
#ifdef LIST_POISONING
node->prev = (struct list_head *) (0x00100100);
node->next = (struct list_head *) (0x00200200);
#endif
}
node->next = NULL;
/**
* list_for_each_safe - iterate over list nodes and allow deletes
* @node: list_head pointer used as iterator
* @safe: list_head pointer used to store info for next entry in list
* @head: pointer to the head of the list
*
* The current node (iterator) is allowed to be removed from the list. Any
* other modifications to the the list will cause undefined behavior.
*/
#define list_for_each_safe(node, safe, head) \
for (node = (head)->next, safe = node->next; node != (head); \
node = safe, safe = node->next)
/**
* list_for_each - iterate over list nodes
* @node: list_head pointer used as iterator
* @head: pointer to the head of the list
*
* The nodes and the head of the list must must be kept unmodified while
* iterating through it. Any modifications to the the list will cause undefined
* behavior.
*/
#define list_for_each(node, head) \
for (node = (head)->next; node != (head); node = node->next)
foreach my $i (@array){;}
@
符號表示註解的開頭,而 \
對於 Doxygen 來說,與 @
意義相同@
會用在參數的開頭,或是一些關鍵字的開頭 (如 @struct
)list_sort
7
QUICKSELECT(list, k)
建立 l1, l2 兩個空的 linled list
r = 從 list 中隨機挑出一個節點中的 val
foreach (node, head)
if noed->val < r
then add(node, l1)
if noed->val > r
then add(node, l2)
if k <= len(l1)
return QUICKSORT(l1, k)
else if k > len(list)-len(l2)
return QUICKSORT(l2, k - (len(list) - len(l2)))
else
return r
原理: 將未排序好的 list 中所有節點,一個個插入到已排序的 list 中適合的位置
list_insertsort
static void list_insertsort(struct list_head *head)
{
struct list_head list_unsorted;
struct listitem *item = NULL, *is = NULL;
INIT_LIST_HEAD(&list_unsorted);
list_splice_init(head, &list_unsorted);
list_for_each_entry_safe (item, is, &list_unsorted, list) {
list_del(&item->list);
list_insert_sorted(item, head);
}
}
這個函式主要做兩件事
list_insert_sorted
static void list_insert_sorted(struct listitem *entry, struct list_head *head)
{
struct listitem *item = NULL;
if (list_empty(head)) {
list_add(&entry->list, head);
return;
}
list_for_each_entry (item, head, list) {
if (cmpint(&entry->i, &item->i) < 0) {
list_add_tail(&entry->list, &item->list);
return;
}
}
list_add_tail(&entry->list, head);
}
要將節點插入排序好的 list 中,分 3 種情況
static void list_qsort(struct list_head *head)
{
struct list_head list_less, list_greater;
struct listitem *pivot;
struct listitem *item = NULL, *is = NULL;
if (list_empty(head) || list_is_singular(head))
return;
INIT_LIST_HEAD(&list_less);
INIT_LIST_HEAD(&list_greater);
pivot = list_first_entry(head, struct listitem, list);
list_del(&pivot->list);
list_for_each_entry_safe (item, is, head, list) {
if (cmpint(&item->i, &pivot->i) < 0)
list_move_tail(&item->list, &list_less);
else
list_move(&item->list, &list_greater);
}
list_qsort(&list_less);
list_qsort(&list_greater);
list_add(&pivot->list, head);
list_splice(&list_less, head);
list_splice_tail(&list_greater, head);
}