在定義整數變數的型態的時候可以加上 unsigned 或是 signed, 例如 unsigned char unsigned short (int) unsigned long (int) unsigned int ---------- signed char signed short (int) signed long (int) signed int -------------- 上面 signed 有加和沒有加是一樣的意義 加上 unsigned 以後, 1. 所需要的資料儲存空間和沒有加 unsigned 時是一樣的 2. 在使用 printf() 列印時基本上你必須分清楚 unsigned 有影響到的是參數的傳遞, 使用 %d 或是 %u 基本上是看程式設計者自己的選擇 int i=-1; printf("%d %u\n", i, i); 會印出 -1 4294967295 unsigned int i=-1; printf("%d %u\n", i, i); 也會印出 -1 4294967295 char i=-1; printf("%d %u\n", i, i); 還是會印出 -1 4294967295 但是 unsigned char i=-1; printf("%d %u\n", i, i); 則會印出 255 255 這不是 %d 和 %u 的問題, 而是 參數傳遞時資料轉換的問題 (見下面第 3 項) 不一樣的地方有下面幾個 1. 資料的範圍基本上加上 unsigned 以後會變成 2 倍 2. 程式裡比較大小的時候 int i=1; int j=-1; if (i>j) printf("i>j\n"); else printf("i<=j\n"); 你會發現結果是 i>j unsigned int i=1; int j=-1; if (i>j) printf("i>j\n"); else printf("i<=j\n"); 你會發現結果是 i<=j 也就是說 signed 和 unsigned 在比較的時候 compiler 會把 signed int 自動當成 unsigned int 來比較 2. 資料轉換的時候 (或是函式呼叫的時候) char i = -128; int j = i; 變數 i 裡面的資料只有 1 個位元組, 要放進 變數 j 裡面的時候需要做 sign extension 也就是多出來的 3 個位元組 (24 個 bit) 都要 填入原來 i 的 sign bit (第 8 個 bit) 以上例來說 (用二進位表示) i: 10000000 j: 11111111 11111111 11111111 10000000 unsigned char i = -128; int j = i; 由 unsigned 轉為 signed 時前面一率補 0 用二進位表示 i: 10000000 j: 00000000 00000000 00000000 10000000 char i = -128; unsigned int j = i; 還是做 sign extension 用二進位表示 i: 10000000 j: 11111111 11111111 11111111 10000000 函式呼叫的時候會做型態的轉變, 例如 void fun(int x) { ... } 呼叫時如果用 unsigned char i=-1; fun(i); 就會自動做轉換 呼叫 printf 時會做 default promotion 因為 printf 函式的定義如下 int printf(const char *format, ...) 其中的 ... 代表可以接受任意型態和個數 的參數, 所有小於四個位元組的整數資料一律 轉換為四個位元組, 浮點數一律轉為八個位元組 所以在轉換時也會根據傳入參數是否有 unsigned 來做 sign extension 4. 可能還有其它不同點我現在一下子想不起來