再談資料型態與含量

我們已經看過以下幾種資料型態 (Data Type),它們的資料含量 (Data Size) 是指每個屬於這種型態的變數,在記憶體中佔據幾個 byte。 以下我們列出所有內建資料型態、和一般編譯程式所定的資料含量。 對每種機器、每種編譯程式,要用 sizeof() 來看看這些資料型態的實際含量。

char 或 signed char
二補數記錄的整數、1 byte:-128 至 127
unsigned char
非負整數、1 byte:0 至 255
short 或 short int 或 signed short 或 signed short int
二補數記錄的整數、2 byte:-32768 至 32767
unsigned short 或 unsigned short int
非負整數、2 byte:0 至 65535
int 或 signed int
二補數記錄的整數、4 byte:-2147483648 至 2147483647
unsigned int
非負整數、4 byte:0 至 4294967295
long 或 long int 或 signed long 或 signed long int
二補數記錄的整數、8 byte:-9223372036854775808 至 9223372036854775807
unsigned long 或 unsigned long int
非負整數、8 byte:0 至 18446744073709551615
float
單精度浮點數、4 byte:8 bits 當做指數,可表達 -126 到 127 之間的指數; 23 bits 當做底數,大約可以表達十進制的 7 位有效數字。
double
雙精度浮點數、8 byte:11 bits 當做指數,可表達 -1022 到 1023 之間的指數; 52 bits 當做底數,大約可以表達十進制的 16 位有效數字。
long double
四倍精度浮點數、16 byte:15 bits 當做指數,可表達 -16382 到 16383 之間的指數; 112 bits 當做底數,大約可以表達十進制的 34 位有效數字。

注意,某些編譯器設定 char 資料型態等同於 unsigned char。 可以用以下方法測試:


#include <stdio.h>

/* 測試 char 是 signed 還是 unsigned (test-char.c) */
main() {
    char c=0;
    int i, n;
    for (i=0; i<256; ++i) {
        if (!(i%16)) putchar('\n');
        n = c;
        printf("%d ", n);
        ++c;
    }
    putchar('\n');
}

其中 m%n 是做 m 除以 n 的餘數, mn 都需是正整數,否則可能有意外的結果。 如果 !(i%16)i 被 16 整除時是 True,否則 False。 這是因為,如果 (i%16)==0 則被當做 False, 所以 !(i%16) 就變成了 True。 因此,上面的程式,每輸出 16 個數就會折下一列。

宣告成非負型態的變數,還是可以定義負數給它。 但是,那個負數是以二補數方法組成的位元組, 而同樣的位元組,又被解釋成正整數。例如以下程式的輸出是 255。


#include <stdio.h>
main() {
    unsigned char c=-1;
    printf("%d\n", c);
}

將 char 或 short 型態之變數值設定給 int 型態之變數時, 在數值上不會有誤差。但是將 int 型態之變數值設定給 char 或 short 型態之變數時, 只取 int 的最小 1 個或 2 個 bytes 交給 char 或 short 型態之變數, 並由接收者自行解釋那位元組所代表的數值。 例如以下程式的輸出是

66047   511   -1
(65536 是 216,256 是 28,255 的二進制數字是 11111111)
#include <stdio.h>

/* 測試 int 型態到 char 和 short 的資料轉換 (int2char.c) */
main() {
    int i=65536+256+255;
    char c=i;
    short s=i;
    printf("%d %d %d\n", i, s, c);
}

習題

  1. 已知「錦」字的 Big-5 碼之第一碼是 192,第二碼與 A 的 ASCII 碼相同。 用 putchar() 輸出一個「錦」字。(注意:192 超過了 char 的資料表現範圍, 而且,要在支援 Big-5 碼的終端機上才執行這個程式。)
  2. 寫一個符合以下規格的函式
    int isleap(int);
    
    參數是一個西元年份,如果是閏年返回 1 (True),否則 0 (False)。 年份需 > 1752。否則一律返回 0。

[ 前一節 ]‧[ 後一節 ]‧[ 回目錄 ]



注意:此處所有文件均為原著,個別的版權宣告日後會一一公布, 整體版面設計亦尚未完成。但仍請勿抄襲文字與圖片,以免觸犯著作權法。

Created: Apr 21, 2000
Last Revised: Apr 21, 2000
© Copyright 2000 Wei-Chang Shann 單維彰

shann@math.ncu.edu.tw