# 資訊創意研究社 - 學過你依然不會的C
共六題,加油喔>_<
測驗期間可以上網
不得使用編譯執行查看輸出
這次考試主要為資料結構及位元運算
google表單:https://goo.gl/3GNhPJ
C99 規格書關鍵字為 `C99 spec`
---
## 測驗 1
### 給定 B 為 2 的某次方 (power of 2) , 請問下列何者等價於 C = A%B?
* `(A)` C = (A | ~(B - 1))
* `(B)` C = (A ^ ~(B - 1))
* `(C)` C = (A & ~(B - 1))
* `(D)` C = (A | (B - 1))
* `(E)` C = (A ^ (B - 1))
* `(F)` C = (A & (B - 1))
---
## 測驗 2
考慮到某些實數的二進位表示形式如同 0.yyyyy... 這樣的無限循環小數,其中 y 是個 k 位的二進位序列,例如 1/3 的二進位表示為 0.01010101...(y = 01),而 1/5 的二進位表示為 0.001100110011...(y = 0011),考慮到以下 y 值,求出對應的十進位分數值。
* y = 010011 => 19/X1
* y = 101 => 5/X2
* y = 0110 => 2/X3
### X1 = ?
* `(A)` 11
* `(B)` 23
* `(C)` 63
* `(D)` 97
* `(E)` 57
* `(F)` 31
* `(G)` 5
* `(H)` 13
### X2 = ?
* `(A)` 17
* `(B)` 19
* `(C)` 13
* `(D)` 11
* `(E)` 3
* `(F)` 7
* `(G)` 23
* `(H)` 97
### X3 = ?
* `(A)` 23
* `(B)` 19
* `(C)` 17
* `(D)` 13
* `(E)` 11
* `(F)` 7
* `(G)` 5
* `(H)` 3
---
## 測驗 3
考慮到以下 C 程式:
```clike=
#include <stdint.h>
#include <stdio.h>
unsigned int ui = 0;
signed int si = -1;
int main() {
int64_t r1 = ui + si;
printf("%lld\n", r1);
}
```
### 在 LP64 的執行環境中,請問輸出為何?
* `(A)` -1
* `(B)` 0
* `(C)` 1
* `(D)` 4294967295
* `(E)` -2147483648
---
## 測驗 4
考慮以下 C 程式,預期輸出結果為何?
```clike=
#include <stdbool.h>
#include <stdio.h>
bool is_one(int i) { return i == 1; }
int main() {
struct { int a : 1; } obj = { .a = 1 };
puts(is_one(obj.a) ? "one" : "not one");
return 0;
}
```
假定 Q1 為 puts 輸出的內容,那應該為何?
### Q1 = ?
* `(A)` one
* `(B)` not one
**Reference:** [Bit field](http://en.cppreference.com/w/cpp/language/bit_field)
---
## 測驗 5
考慮以下程式碼,在 x86_64 搭配 glibc 實作,printf 函示的輸出為何?
```clike=
#include <stdio.h>
union some {
int i; float f;
};
int func(union some *up, float *fp) {
up->i = 123; *fp = -0.0;
return up->i;
}
int main() {
union some u;
printf("%d\n", func(&u, &u.f));
return 0;
}
```
提示: C99 規格書 6.5.2.3 提到:
==If the member used to access the contents of a union object is not the same as the member last used to store > a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type.==
下表為IEEE 754定義的單精度浮點數針對特殊數值的定義
| 類別 | 正負號 | 指數域 | 尾數域 | 數值 |
| -------- | -------- | -------- | -------- | -------- |
| 零 | 0 | 0000 0000 | 000 0000 0000 0000 0000 0000 | 0.0
| 負零 | 1 | 0000 0000 | 000 0000 0000 0000 0000 0000 | -0.0
| 1 | 0 | 0111 1111 | 000 0000 0000 0000 0000 0000 | 1.0
| -1 | 1 | 0111 1111 | 000 0000 0000 0000 0000 0000 | -1.0
| 正無窮 | 0 | 1111 1111 | 000 0000 0000 0000 0000 0000 |+∞
| 負無窮 | 1 | 1111 1111 | 000 0000 0000 0000 0000 0000 | −∞
| NaN | * | 1111 1111 | non zero | NaN
### printf 函式的輸出為
* `(A)` -1
* `(B)` 1
* `(C)` 0
* `(D)` 4294967295
* `(E)` -2147483648
---
## 測驗 6
下圖為一個環狀的Link list的示意圖

分析以下程式碼,推敲 FuncA, FuncB, FuncC 的作用,並且推測程式執行結果。
假設條件:
* malloc 總是成功而且返回的記憶體空間可讀寫
```clike=
#include <stdlib.h>
#include <stdio.h>
struct node { int data; struct node *next, *prev; };
void FuncA(struct node **start, int value) {
if (!*start) {
struct node *new_node = malloc(sizeof(struct node));
new_node->data = value;
new_node->next = new_node->prev = new_node;
*start = new_node;
return;
}
struct node *last = (*start)->prev;
struct node *new_node = malloc(sizeof(struct node));
new_node->data = value;
new_node->next = *start;
(*start)->prev = new_node;
new_node->prev = last;
last->next = new_node;
}
void FuncB(struct node **start, int value) {
struct node *last = (*start)->prev;
struct node *new_node = malloc(sizeof(struct node));
new_node->data = value;
new_node->next = *start;
new_node->prev = last;
last->next = (*start)->prev = new_node;
*start = new_node;
}
void FuncC(struct node **start, int value1, int value2) {
struct node *new_node = malloc(sizeof(struct node));
new_node->data = value1;
struct node *temp = *start;
while (temp->data != value2)
temp = temp->next;
struct node *next = temp->next;
temp->next = new_node;
new_node->prev = temp;
new_node->next = next;
next->prev = new_node;
}
void display(struct node *start) {
struct node *temp = start;
printf("Traversal in forward direction \n");
for (; temp->next != start; temp = temp->next)
printf("%d ", temp->data);
printf("%d ", temp->data);
printf("\nTraversal in reverse direction \n");
struct node *last = start->prev;
for (temp = last; temp->prev != last; temp = temp->prev)
printf("%d ", temp->data);
printf("%d ", temp->data);
printf("\n");
}
int main() {
struct node *start = NULL;
FuncA(&start, 51); FuncB(&start, 48);
FuncA(&start, 72); FuncA(&start, 86);
FuncC(&start, 63, 51);
display(start);
return 0;
}
```
### FuncA 的作用是?
* `(a)` 偵測輸入是否為 circular linked list,若是則將現有所有節點內容排序,否則不做事
* `(b)` 建立兩個節點並且安插在結尾,內容都是 value
* `(c)` 尋找所有節點,當遇到符合給定數值 value 的節點時,將 circular linked list 的開頭和剛找到的節點串接
* `(d)` 建立新節點,內容是 value,並安插在開頭
* `(e)` 建立新節點,內容是 value,並安插在結尾
* `(f)` 建立兩個節點並且安插在開頭,內容都是 value
### FuncB 的作用是?
* `(a)` 偵測輸入是否為 circular linked list,若是則將現有所有節點內容排序,否則不做事
* `(b)` 建立兩個節點並且安插在結尾,內容都是 value
* `(c)` 尋找所有節點,當遇到符合給定數值 value 的節點時,將 circular linked list 的開頭和剛找到的節點串接
* `(d)` 建立新節點,內容是 value,並安插在開頭
* `(e)` 建立新節點,內容是 value,並安插在結尾
* `(f)` 建立兩個節點並且安插在開頭,內容都是 value
### FuncC 的作用是?
* `(a)` 偵測輸入是否為 circular linked list,若是則將現有所有節點內容排序,否則不做事
* `(b)` 建立兩個節點並且安插在結尾,內容分別是 value1 和 value2
* `(c)` 建立兩個節點並且安插在開頭,內容分別是 value1 和 value2
* `(d)` 找到節點內容為 value2 的節點,並在之前插入新節點,內容為 value1
* `(e)` 找到節點內容為 value2 的節點,並在之後插入新節點,內容為 value1
* `(f)` 找到節點內容為 value1 的節點,並在之前插入新節點,內容為 value2
* `(g)` 找到節點內容為 value1 的節點,並在之後插入新節點,內容為 value2
* `(h)` 尋找所有節點,當遇到符合給定數值 value1 和 value2 的兩個節點時,將這兩個找到的節點相互串接
----
**在程式輸出中,訊息 Traversal in forward direction 後依序印出哪幾個數字呢?**
### Z1 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
### Z2 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
### Z3 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
### Z4 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
### Z5 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
---
**在程式輸出中,訊息 Traversal in reverse direction 後依序印出哪幾個數字呢?**
### Z6 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
### Z7 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
### Z8 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
### Z9 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
### Z10 = ?
* `(a)` 63
* `(b)` 86
* `(c)` 51
* `(d)` 48
* `(e)` 72
* `(f)` 這個程式有缺陷,無法正確輸出數字
###### tags: `社團` `題目`