# 2018q3 第 3 週測驗題 :::info 目的: 檢驗學員對 C 語言 pointer, union, bit-fields, 實作 linked list 的認知 ::: --- ### 測驗 `1` 考慮以下程式碼: ```C= #include <stdio.h> #include <stdint.h> struct test { unsigned int x : 5; unsigned int y : 5; unsigned int z; }; int main() { struct test t; printf("Offset of z in struct test is %ld\n", (uintptr_t) &t.z - (uintptr_t) &t); return 0; } ``` 在 GNU/Linux x86_64 環境中執行,得到以下輸出: ``` Offset of z in struct test is 4 ``` 倘若將第 10 和第 11 換為以下: ```C=10 printf("Address of t.x is %p", &t.x); ``` 會發生什麼事? ==作答區== * `(a)` 印出類似 `0x7ffd144e8ad4` 的輸出,也就是 `t` 結構物件的位址; * `(b)` 印出類似 `0x7ffd144e8ad4` 的輸出,和 `t` 結構物件差距 4 bytes; * `(c)` 可以印出數值,但這與編譯器實作有關,不能解讀; * `(d)` 編譯失敗,不能這樣宣告結構體的成員; * `(e)` 編譯失敗,不能將指標指向沒有對齊 1 byte 的結構體成員; 參考資料: [Portable Bit Fields in packetC](https://link.springer.com/content/pdf/10.1007/978-1-4302-4159-1_34.pdf) :::success 延伸問題: 解釋原因,並且找出 C99/C11 規格書對應的描述 ::: --- ### 測驗 `2` 考慮以下程式碼,在 little-endian 硬體上,會返回 `1`,反之,在 big-endian 硬體上會返回 `0`: ```C int main() { union { int a; char b; } c = { .a = K1 }; return c.b == K2; } ``` 補完上述程式碼。 ==作答區== K1 = ? * `(a)` 0 * `(b)` 1 * `(c)` -1 * `(d)` 254 K2 = ? * `(a)` 0 * `(b)` 1 * `(c)` 254 :::success 延伸問題: 解釋運作原理,並找出類似的程式碼 ::: --- ### 測驗 `3` 以下程式碼計算 parity bit: ```C #include <stdint.h> int parity(uint32_t x) x ^= x >> 1; x ^= x >> 2; x = (x & 0x11111111U) * 0x11111111U; return (x >> P) & 1; } ``` 補完程式碼 ==作答區== P = ? * `(a)` 32 * `(b)` 31 * `(c)` 30 * `(d)` 29 * `(e)` 28 * `(f)` 27 * `(g)` 26 * `(h)` 25 * `(i)` 24 :::success 延伸問題: 解釋原理,並且提出更快的實作機制 (提示: 透過 SIMD) ::: --- ### 測驗 `4` 考慮以下程式碼: ```C #include <stdlib.h> #include <string.h> typedef struct rec { char *value; struct rec *next; } record; void insert_sorted(record **r, const char *value) { record *newrec = NULL; while (*r && strcmp(value, (*r)->value) > 0) r = &((F1)->next); newrec = malloc(sizeof(record)); newrec->value = F2(value); newrec->next = F3; F4 = newrec; } ``` 函式 `insert_sorted` 的作用是在 r 所指向已依據數值排序的 linked list 中,安插給定的字串,考慮到 string literal 的生命週期,應該在新建立的節點中,複製給定的字串。 請補完上述程式碼。 ==作答區== F1 = ? * `(a)` r * `(b)` **r * `(c)` *r * `(d)` r->next * `(e)` *r->next F2 = ? * `(a)` 無 * `(b)` strdup * `(c)` strcpy * `(d)` strlen * `(e)` strcmp F3 = ? * `(a)` r * `(b)` **r * `(c)` *r * `(d)` r->next * `(e)` *r->next F4 = ? * `(a)` **r * `(b)` *r * `(c)` r * `(d)` r->next * `(e)` *r->next :::success 延伸問題: 解釋運作原理,並新增刪除和搜尋節點的程式,附上完整的測試計畫 ::: ---