發表文章

目前顯示的是 10月, 2008的文章

Cast a type with a small memory space to a bigger one

這是一個很常見的錯誤,可是我還是犯了 (...sigh) 我當然不是在下面的程式碼犯錯囉,但因為犯錯的程式是工作上的程式,不能貼出來,所以稍作整理,寫出下面的那個「錯誤」程式碼,以資提醒... (為甚麼我有再犯的預感 ...) 下面的程式哪裡有問題: #include "stdio.h" #include "stdlib.h" struct test { unsigned char a; unsigned char b; unsigned char c; }; int main() { struct test tmp; printf("Please enter three number.\n"); printf("Each number should be 0~255\n"); scanf("%d %d %d", &(tmp.a), &(tmp.b), &(tmp.c) ); printf("%d %d %d\n", tmp.a, tmp.b, tmp.c); return 0; } 當我們輸入 1 2 3,顯示也是正常的 1 2 3,看起來一點問題也沒有。 真的嗎???? 讓我們改一下程式碼如下: scanf("%d %d %d", &(tmp.c), &(tmp.b), &(tmp.a) ); printf("%d %d %d\n", tmp.a, tmp.b, tmp.c); 簡單來說,只是把讀取順序反過來,然後一樣輸入 1 2 3,結果答案是 3 0 0 而不是 3 2 1。到底發生了什麼事情??? 首先,當我們用 scanf 進行讀取的時候,是以 int 的方式讀入,也就是說總共讀入了 4 個 byte,所以第一段程式碼可以用下面的那張圖來表示: ----------------------- byte -------------------- +--------+-------+--------+ -------------------- |---a-----|---b---|---c

The difference between Array and Pointer

Array 和 Pointer 有什麼差別呢? 最常聽見的說法是 Array 是 Pointer 的一種特例,是在宣告的時候就已經將大小 allocate 出來的一種 pointer。本來我也是這麼認為的,可是看看下面的那個範例: #include "stdio.h" #include "stdlib.h" int main() { unsigned char test[6]; test[0] = 0; test[1] = 1; test[2] = 2; test[3] = 3; test[4] = 4; test[5] = 5; printf("test: %X\n", test ); printf("&test: %X\n", &test ); printf("*test: %X\n", *test ); printf("*(test+1): %X\n", *(test+1) ); printf("*(&test): %X\n", *(&test) ); return 0; } 顯示的結果如下 test: 76A21CA0 &test: 76A21CA0 *test: 0 *(test+1): 1 *(&test): 76A21CA0 其中 test, *test, *(test+1) 都沒有問題。有問題的是另外兩個。如果 array 和 pointer 是一樣的話,那為甚麼 &test = test 而不是等於 pointer 的 pointer 呢??本來想從 C99 來找答案,但實在不知道從何找起,結果發現網路上有一個很棒的網站: Frequently Asked Questions in comp.lang.c 這個網站用一張圖來解釋其間的差異: +---+---+---+---+---+---+ a: | h | e | l | l | o |\0 | +---+---+---+---+---+---+ +-----+ +---+---+---+---+---+---+ p: