contributed by <plusline
>
- 請補上實驗環境
- 中英文字間請以空白隔開
課程助教
- fixed
- 助教這次作業我已經完成,但還是收到進度落後的通知
- 請問是哪部分寫得不完整嗎?
plusline
作業要求還有提到需「解釋自動評分系統運作的原理」、「提及 qtest 的行為和裡頭的技巧」這兩部份,因為沒看到你的紀錄,而且多天未更新,所以才寄信通知。
應該是你漏掉這部份了XD
還有時間,GOGO!
課程助教
我漏掉那部分的要求,所以開始在看下一周的作業,難怪都沒有共筆可以參考,我會繼續補齊的
plusline
plusline@plusline-System-Product-Name:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
plusline@plusline-System-Product-Name:~$ cat /proc/version
Linux version 4.15.0-34-generic (buildd@lgw01-amd64-047) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #37-Ubuntu SMP Mon Aug 27 15:21:48 UTC 2018
git clone https://github.com/plusline/lab0-c.git
把 repositories 拉到你的linux,這段網址是你的 repositories 的位置。git checkout -b slow-blink
slow-blink 是你要創建的分枝。git commit -a -m 'What you have done'
寫一點註解git push origin slow-blink
提交注意:需要安裝 python 而不是 python3 才能執行 driver.py
。我一直以為是bug,直到打開 driver.py
發現print的格式和我印象中不一樣,才知道原來 python 有兩個分枝。
clang-format -i queue.c
用來排版
make
用來編譯,修改完 queue.h 和 queue.c 後執行。
make test
用來呼叫 driver.py
會幫你的程式評分。
--- TOTAL 0/100
什麼都沒做,所以拿了0分。
void q_free(queue_t *q)
{
/* How about freeing the list elements and the strings? */
/* Free queue structure */
if (q == NULL)
return;
list_ele_t *temp, *current;
current = q->head;
while (current != NULL) {
temp = current;
current = current->next;
// free(temp->value);
free(temp);
}
if (q != NULL)
free(q);
}
用 for 迴圈遍歷,並將所有的節點和字串刪掉,最後再刪掉 queue 。
一直搞不懂為什麼不需要刪掉字串的空間?
bool q_insert_head(queue_t *q, char *s)
{
if (q == NULL)
return false;
list_ele_t *newh;
/* What should you do if the q is NULL? */
newh = malloc(sizeof(list_ele_t));
/* Don't forget to allocate space for the string and copy it */
/* What if either call to malloc returns NULL? */
if (newh == NULL)
return false;
newh->value = strdup(s);
newh->next = q->head;
q->head = newh;
if (q->size == 0)
q->tail = newh;
q->size += 1;
return true;
}
我總覺得直接給 *value 一個給定的大小不太好,但不知道怎做,先將就一下。後來已經修正成用 strdup ,就不用擔心空間大小的問題。
commit 時出現錯誤,但編譯沒報錯:已修正,似乎是 q_insert_head 隨意離開函式引起的。
[queue.c:71]: (error) Memory leak: newh
Fail to pass static analysis.
plusline@plusline-System-Product-Name:~/lab0-c$ make
gcc -O0 -g -Wall -Werror -o qtest qtest.c report.c console.c harness.c queue.o
queue.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:15: recipe for target 'qtest' failed
make: *** [qtest] Error 1
後來發現是不小心輸入 clang-format -i queue.o
,在輸出 queue.o 的檔案( queue.c queue.h )還沒更新前,使用 makefile 並不會執行 gcc -O0 -g -Wall -Werror -c queue.c
,只需要刪掉 queue.o 就可以了。
bool q_remove_head(queue_t *q, char *sp, size_t bufsize)
{
/* You need to fix up this code. */
if (q == NULL || q->size == 0)
return false;
list_ele_t *dummy;
dummy = q->head;
if (sp == NULL)
return false;
strncpy(sp, q->head->value, bufsize - 1);
sp[bufsize - 1] = '\0';
q->head = q->head->next;
free(dummy);
q->size -= 1;
return true;
}
第六個測資是檢測 truncated strings ,測資會故意截斷字串,導致沒有 null terminator ,需要自己將後面一個字元改成'\0'
。
其他的部份照著註解做,都沒有遇到太大的問題。
--- TOTAL 100/100
依照作業手冊,我們知道要評分的時候要在 lab0-c 下執行 make test,我從這裡開始 trace 。打開 Makefile ,找到 test: ,可以知道它呼叫 scripts/driver.py 。
接下來就是 trace driver.py ,從 if __name__ == "__main__":
進入,呼叫 run ,在 run 裡會設定參數,並創建 class Tracer ,並執行 class 中 run 的方法,在這裡它會呼叫放在 traces 資料夾底下所有要測試的題目,其中 subprocess.call 就是用來呼叫這些題目的方式,舉個例子:在15個測資,它需要傳入的參數就是 ['./qtest', '-v', '1', '-f', './traces/trace-15-perf.cmd']
這等於直接在命令列打上./qtest -v 1 -f ./traces/trace-15-perf.com
這個指令執行完,如果這部份的測資答對就會回傳0,答錯就會回傳1,一此判斷加分與否,將所有題目測試完就完成自動評分了。其中 qtest.c 是評分系統判斷作答正確與否的核心,
當不確定輸入的參數數量的時候,可以使用下列這種語法。va_start
void
foo(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;
va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}
要操作這個語法需要宣告一個 va_list 的物件,然後用 va_start 初始化,之間用 va_arg 取值,最後在用 va_list 解構。
練習
void too(char *fmt, ...){
va_list ap;
va_start(ap,fmt);
char *s;
int count=*fmt-48;
printf("%d\n",count);
s=va_arg(ap,char *);
while(count--){
printf("%s\n",s);
s=va_arg(ap,char *);
}
}
int main(){
too("4","lion","tigre","mouton","oiseau");
return 0;
}
4
lion
tigre
mouton
oiseau
要小心用 va_arg 不能取超過參數數量,不然會發生錯誤。
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing