C語言自學《二》下篇---- 類型的轉換、字符類型、枚舉、數學函數

類型的轉換

下面是一個錯誤的輸出,不過經過註釋給出瞭解決辦法,就是經過編譯器自動類型轉換 <!-- lang: cpp -->git

int main(void){    
    //定義了一個float浮點型常量
    const float Revenue_Per_150 = 4.5f;
    short JanSold = 23500;
    short FebSold = 19300;
    short MarSold = 21600;
    float RevQuarter = 0.0f;

    //錯誤一:總銷量的值爲64400,這個值超出了short類型的最大取值範圍
    //short最大取值範圍爲32767
    unsigned long QuarterSold = JanSold + FebSold + MarSold;    //錯誤!輸出爲負數!
    //輸出每個月分別的銷量
    printf("Stock sold in\nJan:%hd\nFeb:%hd\nMar:%hd\n",JanSold,FebSold,MarSold);
    //輸出一個季度的銷量
    printf("Total stock sold in first quarter: %ld\n",QuarterSold);

    //比實際結果值少了1.50
    //因爲QuarterSold是一個整數,因此計算機將除以150後的結果429.333四捨五入
    //因此發生了錯誤,丟失了精度
    //解決此問題的第一個方法:改變下面的運算表達式順序爲:
    //RevQuarter = Revenue_Per_150 * QuarterSold / 150; 這樣計算就正確了
    //第二種解決辦法:把150.0做爲除數,以下:
    //RevQuarter = QuarterSold / 150.0 * Revenue_Per_150;
    RevQuarter = QuarterSold / 150 * Revenue_Per_150;   //錯誤!輸出爲$1930.50!
    printf("Sales revenue this quarter is:$%.2f\n",RevQuarter);
}

####強制類型轉換 像上面的實例,若是能夠把QuarterSold的值轉換爲float類型,該表達式就會議浮點數的方式計算,問題就解決了函數

要把變量從一種類型轉換爲另外一種類型,應該把目標類型放在變量前面的括號中,這種顯示的轉換稱爲強制類型轉換。this

下面是表達式和普通強制轉換類型的例子 <!-- lang: cpp -->設計

//通過像下面這樣修改,進行強制的類型轉換
//通過修改後的表達式,在正確的地方使用正確類型的變量
//當但願保留除法結果的小數部分時,不該使用整數運算
RevQuarter = (float)QuarterSold / 150 * Revenue_Per_150;

//也能夠把表達式的結果從一種類型強轉爲另外一種類型,像下面這樣:
double result = 0.0;
int a = 5;
int b = 8;
result = (double)(a + b) / 2 - (a + b) / (double)(a * a + b * b);

####自動類型轉換code

編譯器在處理設計不一樣類型的值操做時,會按照必定規則吧其中一個操做數的類型轉換爲另外一個操做數的類型,這稱爲隱式類型轉換(implicit conversion)ip

仍是這個例子內存

<!-- lang: cpp -->

//下面的二元運算就進行了隱式自動轉換,能夠分解成下面的樣子
//QuarterSold(64400 int) / 150(int) = 429(四捨五入,捨去了小數部分)
// 429(int) * Revenue_Per_150(4.5 float) = 1930.5(float)
// 在上個步驟中,因爲int類型的值域小於float類型,因此自動將int轉爲float類型
RevQuarter = QuarterSold / 150 * Revenue_Per_150;

#####隱式類型轉換規則 基本規則是:將值較小的操做數類型轉換爲另外一個操做數類型,但在一些狀況下,兩個操做數都要轉換類型ci

如下的規則從高到低排列編譯器

  • 若是是long double,就把另外一個操做數轉換爲long double
  • 不然,若是是double,就把另外一個操做數轉換爲double
  • 不然,若是是float,就把另外一個操做數轉換爲float
  • 不然,若是兩個操做數的類型都是帶符號或無符號的整數,就把級別較低的操做數轉換爲另外一個操做數類型
    • 從左到右從低到高(無符號和有符號級別同樣): char,short,int,long,long long
  • 不然,若是帶符號整數類型的操做數級別低於無符號整數類型的級別,就把帶符號整數類型的操做數轉換爲無符號整數類型
  • 不然,若是帶符號整數類型的值域包含了無符號整數類型所表示的值,就把無符號整數類型轉換爲帶符號整數類型
  • 不然,兩個操做數都轉換爲帶符號整數類型對應的無符號整數類型

#####賦值語句中的隱式類型轉換數學

下面的例子表示了賦值語句的隱式轉換

<!-- lang: cpp -->

int main(void){
    //好吧,別看下面一大長串,其實按照上面的規則很簡單就能看清是如何隱式轉換的
    //首先count(long)轉換爲double類型,ship_cost(float)也轉換爲double類型
    //而後discount(int)轉換爲long類型,long類型再轉換爲float類型
    //通過兩個括號中的計算與轉換,如今是下面這樣的類型表達式
    //long double = double * float
    //而後float轉換爲double
    //最後double轉換爲long double
    //由於long double包含double,因此沒有丟失精度
    double price = 10.0;
    long count = 5L;
    float ship_cost = 2.5F;
    int discount = 15;
    long double total_cost = (count * price + ship_cost) * ((100L - discount) / 100.0F);    
}

###字符類型

####字符的類型定義及賦值

在全部數據類型中,char類型佔用的內存空間最少,它能夠存儲單個字符,它也只能存儲一個整數,因此被當作爲整數類型,也能夠在算術運算中使用它,它的區間是0~255(signed)或者-128~127(unsigned) 單引號內的字符代碼,實際的代碼值取決於計算機環境,但最多見的是美國標準信息交換嗎(ASCII)

代碼示例:

<!-- lang: cpp -->

//下面是給char類型變量指定字符常量,用' '單引號括起來
char letter = 'A';
char digit = '9';
char exclamation = '!';

//也可使用轉義序列指定字符常量
char newline = '\n';
char tab = '\t';
char single_quote = '\';

//還能夠用整數值初始化char類型變量
char character = 74;        //解釋爲J

//使用char進行算術計算
char letter = 'C';
letter += 3;

####字符的輸入輸出

使用scanf()函數和格式說明符%c,能夠從鍵盤上讀取單個字符 一樣用%c能夠輸出字符,用%d輸出字符對應的整數

代碼示例:

<!-- lang: cpp -->

#include <stdio.h>

int main(){
    char ch = 0;
    scanf("%c",&ch);    //獲取鍵盤輸入爲字符類型,存儲到ch字符變量中
    //下面的輸出分別爲一個字符和一個數值
    printf("The character is %c and the code value is %d\n", ch, ch);
}

若是要轉換字符的大小寫,可使用標準庫<ctype.h>頭文件提供的toupper()tolower()函數

###枚舉

####定義枚舉類型和枚舉變量

利用枚舉,能夠定義一個新的整數類型,該類型變量的值域是咱們指定的幾個可能值,下面語句定義了枚舉類型

代碼示例:

<!-- lang: cpp -->

//下面這個語句定義了一個類型,而不是變量,新類型的名稱爲Weekday,稱爲枚舉的標記
//大括號中的值稱爲枚舉常量或者叫作枚舉器,枚舉是一個整數類型,默認從0開始,好比Monday的值就是0,而後逐個遞增
enum Weekday {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

//能夠聲明Weekday類型的一個新變量,並初始化它,以下所示:
//today的值爲2
enum Weekday today = Wednesday;

//或者像下面這樣,定義枚舉類型時,聲明該類型的變量
enum Weekday {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday} today, tomorrow;

//固然也能夠直接初始化
enum Weekday {Monday, Tuesday, Wednesday, Thursday, 
                           Friday, Saturday, Sunday} today=Monday, tomorrow=Tuesday;

//因爲是整數類型,因此也能夠在算術表達式中使用
//要確保給定的枚舉類型使用有效的枚舉值
enum Weekday {Monday, Tuesday, Wednesday, Thursday, 
                           Friday, Saturday, Sunday} today=Monday, tomorrow = today + 1;

####未命名的枚舉類型

未命名枚舉類型的主要限制是,必須在定義該類型的語句中聲明它的全部變量,因爲沒有類型標記名,所以沒法在代碼的後面定義該類型的其餘變量

代碼示例:

<!-- lang: cpp -->

enum {red, orange, yellow, green, blue, indigo, violet} shirt_color;
shirt_color = blue;

###存儲布爾值變量

_Bool類型存儲布爾值,它由true或false組成,前者爲1後者爲0,因此_Bool類型也被看爲整數類型 也能夠用bool做爲類型名稱,這看起來更簡潔,可是要包含<stdbool.h>頭文件

代碼示例:

<!-- lang: cpp -->

#include <stdbool.h>

int main(){
    
    _Bool valid = 1;    //true
    _Bool valid = 0;    //false
    _Bool valid = true;
    _Bool valid = false;
    bool valid = 1;
    bool valid = 0;
    bool valid = true;
    bool valid = false;
}

###數學函數

<math.h>頭文件包含各類數學函數的聲明,全部的函數都返回一個double類型 不過經過在函數後面添加lf,分別能夠返回long doublefloat類型 這裏就不詳細列舉數學函數了,用時再查找

相關文章
相關標籤/搜索