天天看點

c primer plus 專題3:資料和C

1 示例程式

platinum.c

/* platinum.c -- your weight in platinum */
#include <stdio.h>

int main(void)                 
{
    float weight;       /* 你的體重          */
    float value;        /* 相同重量的白金價值 */

    printf("Are you worth your weight in platinum?\n");
    printf("Let's check it out.\n");
    printf("Please enter your weight in pounds: ");

    /* 擷取使用者的輸入                        */
    scanf("%f", &weight);
    /* 假設白金的價格是每盎司$1700            */
    /* 14.5883用于把英鎊常衡盎司轉換為金衡盎司 */
    value = 1700.0 * weight * 14.5833;
    printf("Your weight in platinum is worth %.2f.\n", value);
    printf("You are easily worth that! If platinum prices drop,\n");
    printf("eat more to maintain your value!\n");

    getchar();

    return 0;
}
           

編譯程式,會出現從“double”轉換到“float”,可能丢失資料

原因是 1700.0 從double 轉為了 float 類型。

c primer plus 專題3:資料和C

執行結果:

c primer plus 專題3:資料和C

資料類型關鍵字:

c primer plus 專題3:資料和C

浮點數的存儲方式:

特殊的存儲方式,決定了浮點數可能會丢失精度。

c primer plus 專題3:資料和C

浮點數的存儲格式:0.3141E1。

c primer plus 專題3:資料和C
2 資料類型

1 字長:

c primer plus 專題3:資料和C

可以看到,字長實際上是處理器資料總線的寬度,反映了CPU一次能夠讀取多少位的資料。

2 int

c primer plus 專題3:資料和C

可以看到,int 通常占用一個機器字長的存儲空間。16位機(8086)中的 int 為16位,32位機(如stm32)中的 int 為32位。

int 類型變量的聲明與初始化

c primer plus 專題3:資料和C

八進制和十六進制

在C語言中,以特定的字首表示使用哪種進制。如0X或0x字首,表示十六進制,是以十進制數16,表示成16進制為0X10;類似的,0字首表示八進制,十進制數16表示成8進制為020。

c primer plus 專題3:資料和C
c primer plus 專題3:資料和C

列印選項:%o 以八進制列印;  %x 以十六進制列印;

如果要顯示0和0x字首,要在轉換說明中加#,如%#o  %#x  %#X

/* 以十進制 八進制 十六進制列印十進制數100 */
#include <stdio.h>

int main(void)
{
	int x = 100;

	printf("十進制 = %d\t八進制 = %o\t十六進制 = %x\n", x, x, x);
	printf("十進制 = %d\t八進制 = %#o\t十六進制 = %#x\t十六進制 = %#X\n", x, x, x, x);

	return 0;
}
           

運作結果:

十進制 = 100    八進制 = 144    十六進制 = 64
十進制 = 100    八進制 = 0144   十六進制 = 0x64 十六進制 = 0X64
           

其他整型變量

short int 占用的空間可能比 int 少,long int 占用的空間可能比 int 多;

long long int 占用的空間可能比 long int 多,而且該類型至少占據 64 位;

long 常量和 long long 常量

通常情況下,編譯器會根據常量的值,來自動确定常量的類型。但有時需要用 long 來存儲較小的值,如記憶體位址。此時,可以通過增加字尾L來強行變為 long 類型。

c primer plus 專題3:資料和C

列印 short  long  unsigned 類型

c primer plus 專題3:資料和C

3 char

1 字元變量的聲明

c primer plus 專題3:資料和C

2 轉義序列

c primer plus 專題3:資料和C
#include <stdio.h>

int main(void)
{
	printf("Gramps sez, \" \\ is a backslash.\"\n");

	return 0;
}
// 輸出
Gramps sez, " \ is a backslash."
           

%c 列印字元

c primer plus 專題3:資料和C

可移植類型:stdint.h

c primer plus 專題3:資料和C

4 _Bool

布爾類型:_Bool,包含頭檔案 stdbool.h,布爾類型取值 true 和 false

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    _Bool logic = true;

    if (logic)
    {
        printf("This is logic \"true\"\n");
    }

	return 0;
}
           

5 浮點型

1 float 至少能精确到6位有效數字,double 至少能精确10位有效數字,long double 精度至少與 double 相同。

c primer plus 專題3:資料和C
c primer plus 專題3:資料和C

預設情況下,編譯器假定浮點型常量是 double 類型的精度。例如,假設 some 是 float 類型的變量,編寫下面的語句:

float some = 2.0 * 4.0;
           

通常,2.0和4.0被存儲為64位的 double 類型,使用雙精度的乘法計算,然後将乘積截斷成 float 類型的寬度。這樣做雖然精度更高,但是會減慢程式的運作速度。

在浮點數後加上 f 或 F 字尾可覆寫預設設定,編譯器會将 浮點型常量看作 float 類型。使用 l 或 L字尾,可以将浮點型常量看作 long double 類型。如果不加字尾 f ,編譯時可能會提示警告如下:

warning C4244: “=”: 從“double”轉換到“float”,可能丢失資料

2 列印浮點值

c primer plus 專題3:資料和C

3 類型大小 sizeof

sizeof是C語言的内置運算符,以位元組為機關給出指定類型的大小。C99提供%zd轉換說明,來比對sizeof的傳回類型。一些不支援C99和C11的編譯器,可以用%u或%lu代替%zd。

#include <stdio.h>

int main(void)
{
    /* %zd 比對 sizeof 的傳回類型 */
    printf("Type int have %zd bytes.\n", sizeof(int));
    printf("Type float have %zd bytes.\n", sizeof(float));
    printf("Type double have %zd bytes.\n", sizeof(double));

    return 0;
}
           

6 使用資料類型

類型轉換

浮點數(float double)轉換成整數(int)類型時,小數部分會直接截斷

#include <stdio.h>

int main(void)
{
    int cost = 12.99;

    printf("cost is %d.\n", cost);

    return 0;
}
// 編譯提示
“初始化”: 從“double”轉換到“int”,可能丢失資料
cost is 12.    // 小數部分直接截斷
           

7 重新整理緩沖區

c primer plus 專題3:資料和C