2018q1 第 9 週測驗題
測驗 1
考慮以下程式碼:
已知程式輸出的第一行為 (0.99)^100: 0.366032
,第二行和第三行輸出分別是 (100)^0.99: X1
與 (0.99)^100: X2
,依據 IEEE 754 規範,求 X1 和 X2 的值。
X1 = ?
(a)
99.000000
(b)
95.499258
(c)
1.000000
(d)
0.000000
(e)
-1.000000
X2 = ?
(a)
1.000000
(b)
0.366032
(c)
0.133979
(d)
0.000000
(e)
-1.000000
測驗 2
考慮到以下採用 Functional Programming 風格開發的 singly-linked list 程式:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct __int_list const *const int_list_t;
static int_list_t const Nil = NULL;
typedef struct __int_list {
int_list_t next;
int32_t const val;
} node_t;
typedef void *const CPS_Result;
typedef void (*MakeListCallback)(int_list_t list, CPS_Result res);
void make_list(uint32_t const arr_size,
int32_t const array[],
int_list_t lst,
MakeListCallback const cb,
CPS_Result res);
typedef void (*ReversedListCallback)(int_list_t rlist, CPS_Result res);
void reverse(int_list_t list,
int_list_t rlist,
ReversedListCallback const cb,
CPS_Result res);
typedef void (*VoidMappable)(int32_t const val);
void void_map_array(VoidMappable const cb,
uint32_t const size,
int32_t const *const arr);
void list2array(int_list_t list, CPS_Result res);
void reverse_toarray(int_list_t list, CPS_Result res) {
reverse(list, Nil, list2array, res);
}
static void print_val(int32_t const val) { printf("%d ", val); }
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
int main(int argc, char *argv[]) {
int32_t arr[] = {99, 95, 90, 85, 80, 20, 75, 15, 10, 5};
uint32_t const arr_size = ARRAY_SIZE(arr);
int32_t res[arr_size];
make_list(arr_size, arr, Nil, reverse_toarray, res);
void_map_array(print_val, arr_size, res);
printf("\n");
return 0;
}
void make_list(uint32_t const arr_size,
int32_t const arr[],
int_list_t lst,
MakeListCallback const cb,
CPS_Result res) {
if (!arr_size) {
cb(lst, res);
return;
}
make_list(arr_size - 1, arr,
&(node_t){.val = arr[arr_size - 1], .next = lst}, cb, res);
}
void list2array(int_list_t list, CPS_Result res) {
if (Nil == list)
return;
int32_t *array = res;
array[0] = list->val;
list2array(list->next, array + 1);
}
void reverse(int_list_t list,
int_list_t rlist,
ReversedListCallback const cb,
CPS_Result res) {
if (Nil == list) {
cb(rlist, res);
return;
}
reverse(list->next, &(node_t) K1, cb, res);
}
void void_map_array(VoidMappable const cb,
uint32_t const size,
int32_t const *const arr) {
if (!size)
return;
cb(arr[0]);
void_map_array(cb, K2, K3);
}
程式輸出為 5 10 15 75 20 80 85 90 95 99
,也就是將輸入的數值順序予以反轉,過程中不需要 malloc/free,請補完上述程式碼。
K1 = ?
(a)
{.val = list->val, .next = list}
(b)
{.val = list->val, .next = rlist}
(c)
{.val = rlist->val, .next = list}
(d)
{.val = rlist->val, .next = rlist}
K2 = ?
(a)
size - 1
(b)
size
(c)
size + 1
K3 = ?
(a)
arr - 1
(b)
arr
(c)
arr + 1
延伸題目:
- 解釋上述程式碼的運作,並且透過修改和實驗,理解 functional programming (FP) 風格;
- 比照 FP,改寫上述程式碼,實作出 quick sort,同樣不得配置 heap memory (也就是不得用 malloc/free);
- 測試這樣的 integer list 和 non-intrusive linked list 的效能差異;