# 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 延伸問題: 解釋運作原理,並新增刪除和搜尋節點的程式,附上完整的測試計畫 ::: ---
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.