C語言核心技術-基本數據類型及其應用

C語言核心技術-基本數據類型及其應用

3.1 整數

3.1.1 整數常量

C語言整數常量可使用u後綴表示位無符號整數,使用l後綴表示long類型的整數,使用ll後綴表示爲long long類型的整數html

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
/* 整數常量 整數常量分爲整型、長整型、長長整型 同時每種整型還有有符號和無符號兩種類型 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    printf("有符號整數常量%d \n",100);
    printf("無符號整數常量%d \n",100u);

    printf("有符號長整數常量%ld \n", 2147483647L);
    printf("無符號長整數常量%lu \n", 2147483647UL);

    printf("有符號長長整數常量%lld \n", 9223372036854775807LL);
    printf("無符號長長整數常量%lld \n",  9223372036854775807ULL);
    system("pause");
    return 0;
}

3.1.2 整數的三種進制類型

C語言中的整型常量支持八進制、十進制和十六進制三種進制類型,不支持二進制。web

  • 八進制由0-7之間的八個整數組成,八進制的常量值是以0開頭。
  • 十進制由0-9之間的十個整數組成。
  • 十六進制由0-9,a-f之間的十個整數加上6個字母組成。
    printf()函數針對整數的三種進制類型提供了對應的輸出格式,其中八進制輸出使用%o表示,十進制使用%d表示,十六進制使用%f表示,#表示輸出進制的完整格式,例如八進制會在最左邊填充一個0,十六進制會在最左邊填充0x。

不一樣進制的輸出不會改變數據原來的值,底層依然是以二進制存儲,只是輸出的表現形式變了。編程

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 整數的三種進制輸出形式 八進制 十進制 十六進制 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //定義整型變量,初始化值爲100
    int number = 100;
    //雖然輸出結果有變化,可是原始number的值是沒有變化的
    printf("100以八進制輸出的結果是%#o\n",number);
    //不一樣進制的輸出不會修改數據,只是數據的表現形式發生了變化。
    printf("100以十進制輸出的結果是%d\n", number);
    //# 表示將進制的完整表現形式輸出 例如十六進制的值是以0x開頭,八進制的值是以0開頭
    printf("100以十六進制輸出的結果是%#x\n", number);

    system("pause");
    return 0;
}

3.1.3 跨平臺的整數

爲了解決不一樣平臺,相同的類型佔據的大小不一致的問題,C語言標準委員會在C99標準中提出了跨平臺的整數,在<stdint.h>頭文件中定義,意味着一樣的類型在不一樣的系統下的大小是一致的。
例如int64_t在全部實現C99標準的編譯器下佔據的都是8個字節,int32_t在全部實現C99標準的編譯器下佔據的都是4個字節。windows

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/* @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    long val = 100;
    printf("windows下long佔據的字節數量是%d\n", sizeof(val));

    //在不一樣的平臺下佔據都是32字節
    int32_t int_32_MAX_VALUE = INT32_MAX;
    printf("sizeof(int_32_MAX_VALUE ) = %d\n", sizeof(int_32_MAX_VALUE));
    printf("int_32_MAX_VALUE = %d\n", int_32_MAX_VALUE);


    //在不一樣的平臺下佔據都是64字節
    int64_t int_64_MAX_VALUE = INT64_MAX;
    printf("sizeof(int_64_MAX_VALUE ) = %d\n", sizeof(int_64_MAX_VALUE));
    printf("int_64_MAX_VALUE = %lld\n", int_64_MAX_VALUE);
    system("pause");
    return 0;
}

3.1.4 整數的極限

整數按照佔據不一樣的字節大小能夠分爲short,int,long和long long 四種類型,它們默認是有符號(signed)類型用於存儲正負數,而對應的無符號類型(unsigned)則用來存儲非負數的整數。
整數的極限定義在<limits.h>頭文件中定義,Visual Studio 2019中能夠選中一個極限值常量,而後使用快捷鍵F12轉到定義,直接查看常量值的表示範圍。數組

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 三種整數類型的有符號和無符號的極限 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    printf("short能存儲的最大值是%d\tshort能存儲的最小值是%d,佔據的字節數量是%d\n\n\n", SHRT_MAX, SHRT_MIN, sizeof(short));
    printf("unsigned short能存儲的最大值是%d\n\n", USHRT_MAX);
    //32位和64位系統 int和long是等價的
    printf("int能存儲的最大值是%d\tint能存儲的最小值是%d,佔據的字節數量是%d\n\n", INT_MAX, INT_MIN, sizeof(int));
    printf("unsigned int能存儲的最大值是%u\n\n", UINT_MAX);
    //無符號的整數 最小值都是0 即不能表示負數
    printf("long能存儲的最大值是%d\tlong能存儲的最小值是%d,佔據的字節數量是%d\n\n", LONG_MAX, LONG_MIN, sizeof(long));
    printf("long long能存儲的最大值是%lld\tlong long能存儲的最小值是%lld,佔據的字節數量是%d\n\n", LLONG_MAX, LLONG_MIN, sizeof(long long));
    printf("unsigned long long 能存儲的最大值是%llu\n", ULLONG_MAX);
    system("pause");
    return 0;
}

3.1.5 整數的注意事項和案例

在使用整數參與運算時,須要考慮到數據範圍對應的極限,不然會發生錯誤的結果微信

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 整數運算的越界 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //爲了保證結果運算正確,必須在極限範圍以內
    printf("無符號short int所能存儲的最大值是%d\n", USHRT_MAX);

    unsigned short int  shortnum = 65536;
    printf("shortnum=%d", shortnum); //結果爲0 由於chnum所能表示的最大值爲65535,這裏發生了越界,結果錯誤
    system("pause");
    return 0;
}

若是想要存儲身份證號等超大類型的整數數據,可使用無符號的long long類型來存儲網絡

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* long long 類型的應用場景 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    unsigned long long mobilePhone = 18601767221;
    printf("mobilePhone=%llu\n", mobilePhone);
    unsigned long long qq = 1079351401;
    printf(" qq = %llu", qq);
    system("pause");
    return 0;
}

根據給出的三角形三條邊,使用頭文件<math.h>中的sqrt函數計算三角形的面積函數

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* 根據給出的邊長求面積 使用math.h文件中提供的開平方根函數 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //根據給出的邊長求面積
    //使用math.h文件中提供的開平方根函數
    int a = 6;
    int b = 8;
    int c = 10;
    int p = (a + b + c) / 2;
    //sqrt返回float,這裏使用賦值運算完成了類型轉換
    int s = sqrt(p * (p - a) * (p - b) * (p - c));
    printf("三角形的面積是%d\n", s);
    system("pause");
    return 0;
}

3.2 浮點數

3.2.1 浮點型常量

浮點型即生活中使用的小數類型(例如3.14),例如帳戶的餘額,銀行的存款利率等等都是浮點型。
C語言中按照精度的不一樣分別使用float,double和long double表示,默認浮點類型是double,float佔據四個字節,double佔據8個字節,long double大於等於8個字節,Windows 32位和64位系統long double都是8個字節,Ubuntu18.04系統下long double是佔據16個字節。大數據

浮點數的常量可使用十進制的小數和科學計數法表示,科學計數法能夠存儲特大或者特小的數字ui

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 浮點型常量 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //輸出結果顯示3.14佔據8個字節,由於浮點數默認是double類型
    printf("浮點數3.14佔據的字節數量是%d\n", sizeof(3.14));
    //若是以f結尾的就是float類型
    printf("浮點數3.14f佔據的字節數量是%d\n", sizeof(3.14f));



    //十進制
    float flt = 12.0f; //小數後面加f表示float類型
    double dbl = 12.0; //小數默認是double類型
    //科學計數法
    double db1 = 0.12e3;
    //e以前必須有數字,指數必須爲整數
    double db2 = 12000.124e5; //e5表示10的5次方
    //%f默認輸出小數點後六位
    printf("flt = %f \n", flt);
    printf("db1 = %f \t db2 = %f\n", db1, db2);
    system("pause");
    return 0;
}

3.2.2 浮點數變量

在初始化浮點數變量時,默認值建議爲0.0或者0.0f,賦值時變量的值和變量的類型保持一致。
printf()函數輸出float類型的變量使用格式符%f,輸出double類型的變量使用%lf。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //在賦值時儘可能保證賦值號(=)左右兩邊類型一致,若是將表示範圍大的值賦值給表示範圍小的變量,可能會形成數據溢出,
    float flt = 3.14f;
    printf("flt = %f \n", flt);
    flt = 0.0f;
    printf("flt = %f \n", flt);

    double dbl = 5.67;
    //printf()默認輸出小數後6位數
    printf("dbl = %lf \n", dbl);
    //若是隻要輸出小數點後2位數,可使用格式符 %.2lf 實現
    printf("dbl = %.2lf \n", dbl);

    //請輸入一個浮點數
    printf("請輸入一個浮點數\n");
    scanf("%lf", &dbl);
    //輸出結果爲保留小數點後兩位
    printf("你輸入的浮點數是%.2lf \n", dbl);
    system("pause");
    return 0;
}

3.2.3 浮點數極限

C語言在<float.h>的頭文件中使用常量定義了float和double以及long double的極限值,咱們可使用sizeof()關鍵字求出float,double和long double的字節數量以及使用。
常量FLT_MAX,FLT_MIN求出float表示的最大值和最小值以及DBL_MAX,DBL_MIN求出double所能表示的最大值和最小值。

在windows上double和long double是等價的,可是在Linux(例如Ubuntu 18.04上)long double是佔據16個字節,這也就意味着long double的極限比double更大。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
/* 浮點數的極限 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {

    printf("float佔據的字節數量是%d\n", sizeof(float));
    printf("float能存儲的最大值是%e\t float能存儲的最小值是%e \n", FLT_MAX, FLT_MIN);
    printf("\n");
    printf("double佔據的字節數量是%d \n ", sizeof(double));
    printf("double能存儲的最大值是%e\t double能存儲的最小值是%e \n", DBL_MAX, DBL_MIN);
    printf("\n");
    printf("long double佔據的字節數量是%d\n", sizeof(long double));
    printf("long double 能存儲的最大值是%e\t long ouble能存儲的最小值是%e \n", LDBL_MAX, LDBL_MIN);
    system("pause");
    return 0;
}

3.2.4 浮點數存儲機制

首先明確一點,不管是整型、浮點型仍是字符等等數據類型在計算機底層都是以二進制的方式存儲的。

浮點數在內存中的存儲和整數不一樣,由於整數均可以轉換爲一一對應的二進制數據。
而浮點數的存儲是由符號位(sign)+指數位(exponent)+小數位(fraction)組成。
其中float是由1位符號位+8位指數+23位小數組成,
而double是由1位符號位+11位指數位+52位小數位組成。

int和float一樣佔據四個字節的內存,可是float所能表示的最大值比int大得多,其根本緣由是浮點數在內存中是以指數的方式存儲。
咱們都知道在內存中,一個float類型的實數變量是佔據32位,即32個二進制的0或者1組成

四字節浮點數 最左邊的第一位是最高位

0000 0000 0000 0000 0000 0000 0000 0000

從低位依次到高位叫第0位和第31位,這32位能夠由三部分組成:

符號位:第31位數表示符號位,若是爲0表示整數,若是爲1表示負數
指數:第23位到第30位,這8個二進制表示該實數轉化爲規格化的二進制實數後的指數與127(127即所謂的偏移量)之和所謂階碼,規格化的二進制實數只能在-127-127之間。
小數位:第0位到第22位,最多能夠表示23位二進制小數,不然超過了就會產生偏差。

3.2.5 浮點數使用注意事項

float佔據四個字節,提供的有效位是6-7位,而double佔據八個字節,提供的有效位數是15-16位,若是在使用float或者double表示實數時超過有效數字,若拿來進行關係運算(例如等於)的話,會獲得一個錯誤的結果。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 浮點數相等性判斷 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    float flt1 = 1.00000000001;
    float flt2 = 1.00000000000000000001;
    //由於float的有效數字是6-7位 這裏超出有效數字 計算不許確
    printf(" flt1 == flt2 ? %d\n", (flt1 == flt2)); // 輸出結果1表示相等 0則表示不相等

    //double精確的有效位數是15-16位,這裏也超出了有效數字,計算不夠正確 
    double db1 = 1.00000000000000000000000000000001;
    double db2 = 1.000000000000000000000000000000000000000000000000000000000000000000000000000000001;

    printf(" db1 == db2 ? %d\n", (db1 == db2)); // 輸出結果1表示相等 0則表示不相等
    system("pause");
    return 0;
}

中美GDP計算

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* 給出當前美國和中國的GDP以及增加率,使用math.h的pow函數實現計算出中國GDP超過美國GDP的年份 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //當前中美GDP
    double ch_current_gdp = 14.6;
    double us_current_gdp = 20.5;

    //當前中美GDP的增加率
    double ch_rate = 1.06;
    double us_rate = 1.04;

    double ch_gdp = 0.0;
    double us_gdp = 0.0;
    int year = 2018;
    for (int i = 1; i <= 100; i++) {
        //使用pow函數計算中美每一年增加後的GDP
        ch_gdp = ch_current_gdp * pow(ch_rate, i);
        us_gdp = us_current_gdp * pow(us_rate, i);
        year++;
        printf("%d年中國的GDP是%f\n", year, ch_gdp);
        printf("%d年美國的GDP是%f\n", year, us_gdp);

        if (ch_gdp > us_gdp) {
            printf("在%d年,中國的GDP超越了美國的GDP", year);
            break;
        }

    }

    system("pause");
    return 0;
}

3.3 字符

3.3.1 字符型常量

在平常開發應用中,字符是最經常使用的數據類型。由於生活中的許多數據都是經過字符表示,而不是數字表示,字符能表示更多的含義,最典型的就是網絡協議,例如超文本傳輸協議HTTP協議。

C語言中字符使用一對單引號('')表示,注意單引號只能做用域一個字符。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 字符常量 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //輸出英文字符
    printf("輸出英文字符%c\n", 'a');
    printf("char佔據的字節數量是%d\n", sizeof(char));
    system("pause");
    return 0;
}

C語言中的char只佔用1個字節,所以不能存儲中文,若是想要存儲中文,須要使用wchar_t類型存儲,而後還要進行本地化的設置。

#define _CRT_SECURE_NO_WARNINGS
#include <locale.h> //引入本地化的頭文件
#include <stdio.h>
#include <stdlib.h>
/* C語言中文存儲 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //設置本地化
    setlocale(LC_ALL, "chs");
    wchar_t ch = L'劉'; //使用wprintf()函數輸出中文 wprintf(L"ch = %c \n", ch); system("pause"); return 0; }

除了使用prinf函數結合%c輸出字符之外,C語言還提供了putchar()函數來輸出字符

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 輸出字符的幾種方式 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
    char c = 'A';
    putchar(c);
    printf("\n");
    printf("c = %c \n", c);
    system("pause");
    return 0;
}

3.3.2 字符的本質

因爲計算機最底層只能識別二進制的數據,可是字符不是二進制的數據。
若是將字符和特定的數值一一對應起來,這張對應表就是ASC||表。
若是字符變量ch存儲的字符是'z',那麼實際上存儲的是字符z對應的ASC||值即整數122。即字符變量存儲的本質就是存儲的字符對應的ASC||值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 字符與asc||碼錶 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //聲明並初始化字符變量ch,初始化值爲z
    char ch = 'z';
    printf("char ch = %c \n", ch);
    printf("字符變量%c對應的整數是%d \n", ch, ch);
    printf("char佔據的字節大小是 %u \n", sizeof(ch));

    system("pause");
    return 0;
}

平常開發中最經常使用的字符就是大小寫字母以及數字字符
咱們能夠藉助printf()函數的格式%c和%d實現輸出字符對應的ASC||值。
數字字符'0'表示的整數是48,小寫字符'a'表示的整數是97,大寫字符'A'表示的整數時65。數字0表示空字符。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 字符的本質 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    char ch = '0';
    printf("字符%c對應的整數是%d\n", ch, ch);
    ch = 'a';
    printf("字符%c對應的整數是%d\n", ch, ch);
    ch = 'A';
    printf("字符%c對應的整數是%d\n", ch, ch);

    int number = 97;
    printf("數字%d對應的字符是%c\n", number, number);
    number = 65;
    printf("數字%d對應的字符是%c\n", number, number);
    number = 48;
    printf("數字%d對應的字符是%c\n", number, number);
    system("pause");
    return 0;
}

3.3.3 轉義字符

一些特殊的符號沒法直接顯示時,咱們使用\特殊字符來表示。
例如\a表示發聲,沒法在終端上直接顯示。
在平常開發中還會使用到各類經常使用的轉義字符,例如\t實現tab的效果。
轉義字符\n實現換行的效果,轉義字符\實現路徑轉義。
%%輸出百分號。
轉義字符還可使用八進制和十六進制表示,用於表示字符對應的ASC||碼值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 轉義字符 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //聲音沒法輸出在屏幕上顯示,所以這裏使用轉字符\a實現發聲
    printf("%c", '\a');
    //平常開發中經常使用的轉移字符 \n實現換行
    printf("hello \n");
    printf("world \n");
    // \t 實現tab效果
    printf("C\t語\t言\t核\t心\t編\t程\n");
    // \r 實現光標移到行首 因爲光標移到行首,最終只會輸出C語言核心編程
    printf("CPrimerPlus%cC語言核心編程\n", '\r');
    //路徑轉義 \\表示路徑轉義 
    //使用system函數使用電腦上的微信,調用成功的前提條件是電腦上安裝了微信
    system("\"C:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe\"");
    // %%實現輸出百分號
    printf("合格率爲%%%d\n", 90);

    //八進制轉義和十六進制轉義
    //八進制的62轉換爲十進制是50,50表示字符2
    char ch = '\62';
    printf("八進制的轉義字符62轉換爲字符的結果是%c \n", ch);//2
    //十六進制的62轉換爲十進制是98,98表示的字符是b
    ch = '\x62';
    printf("十六進制的轉義字符62轉換爲字符的結果是%c\n", ch); //b
    system("pause");
    return 0;
}

3.3.4 字符的應用

既然字符變量的本質存儲的ASC||值,即整數。所以字符也能夠參與加減運算。
因爲ASC||碼規定了小寫字母''a' 表示97,而後一次遞增,小寫字母'z'表示122,而大寫字母'A'表示65,而後依次遞增,大寫字母'Z'表示90。所以根據這個規律能夠經過加減運算實現大小寫字母轉換。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 字符的大小寫轉換 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    // 小寫轉大寫
        char lower_ch = 'a';
    // 0x20就是十進制的32
    char upper_ch = lower_ch - 0x20;

    printf("小寫字母%c轉換爲大寫字母的結果是%c \n", lower_ch, upper_ch);


    //大寫轉小寫
    upper_ch = 'A';
    lower_ch = upper_ch + 32;
    printf("大寫字母%c轉換爲小寫字母的結果是%c \n", upper_ch, lower_ch);


    system("pause");
    return 0;
}

3.4 布爾

bool類型只有兩個值,即true和fasle,它們在內存中分別使用1和0表示,這樣一個字節即可以存儲bool類型的變量。
在C程序中使用bool類型的變量,須要引入頭文件stdbool.h,後續的各類邏輯、關係運算以及選擇結構if/else和while循環會大量使用bool類型的變量。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/* bool類型及其應用 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
    bool flag = true;
    //佔據的字節數量爲1
    printf("bool佔據的字節數量是%d\n", sizeof(flag));
    //成立的結果爲1
    printf("bool = %d\n", flag);

    flag = false;
    //不成立的結果爲0
    printf("bool = %d\n", flag);


    //bool在if/else結構和關係運算的使用
    int age = 20;
    bool isAdult = age > 18;
    if (isAdult == 1) {
        printf("你成年了\n");
    }
    else {
        printf("你沒有成年\n");
    }
    system("pause");
    return 0;
}

3.5 數據類型轉換

3.5.1 數據自動類型轉換

當多種數據類型(整數、浮點數、字符)同時參與運算時,會發生自動類型轉換,容量小的數據類型的變量與容量大的大數據類型的變量作運算時,結果自動提高爲容量大的數據類型,防止運算時超過極限值,防止運算結果的精度丟失。此時容量大小指的是,數據類型表示數的範圍大小,而不是佔用內存大小,好比float容量大於long的容量。

自動類型轉換的規則以下

char,short->int->long->float->double->long double

其中對應的有符號類型還會自動轉換爲無符號類型,char和char運算,short和short運算也會轉換爲int。

char和int,double的自動類型轉換

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 數據類型自動轉換 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    char ch = 'A';
    printf("1.0佔據的字節數量是%d\n", sizeof(1.0));
    //ch+1自動轉換爲int類型,所以佔據四個字節
    printf("字符變量ch+1的字節數量是%d\n", sizeof(ch + 1));
    printf("字符變量ch+1.0的字節數量是%d\n", sizeof(ch + 1.0));
    system("pause");
    return 0;
}

int和unsigned int的自動類型轉換

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 自動類型轉換 有符號類型int轉換爲無符號類型int @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    int number1 = -10;
    unsigned int number2 = 5;

    //有符號數和無符號數參與運算時,先將有符號數轉換爲無符號數

    printf("number1按照無符號輸出結果爲%u\n", number1);
    int result = number1 + number2;

    //使用三目運算和算術運算輸出表達式number1+number2大於0仍是小於0
    //由於number1按照無符號的結果是4294967286 所以結果是大於0
    number1 + number2 > 0 ? printf("number1 + number2 > 0 \n") : printf("number1 + number2 < 0 \n");
    printf("按照有符號整數輸出 result = %d \n", result);
    printf("按照無符號整數輸出 result = %u \n", result);

    system("pause");
    return 0;
}

char、short的自動類型轉換:因爲char,short佔據的內存空間太小,編譯器規定,只要是char,short參與運算,都會自動轉換爲int類型。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* char、short的自動類型轉換:因爲char,short佔據的內存空間太小,編譯器規定,只要是char,short參與運算,都會自動轉換爲int類型。 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    char x = 10;
    int target = x + x;

    short s = 20;
    int short2 = s + s;
    int result = x + s;
    system("pause");
    return 0;
}

3.5.2 數據強制類型轉換

強制類型轉換就是在待轉換的表達式的左邊使用強轉符(目標類型)實現

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 數據強制類型轉換 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {

    float fl = 10.8;
    float flt = 10.3;
    int num = (int)fl + flt; //20.3 先把fl強制轉換爲int類型,而後再和flt相加,再轉換爲int,由於賦值會進行自動類型轉換
    printf("num =%d\n", num);
    num = (int)(fl + flt);//21 先把fl和flt相加後,強制轉換爲int
    printf("num =%d\n", num);
    system("pause");
    return 0;
}

強制類型轉換隻是臨時改變變量的值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 強制類型轉換的特性 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    float flt = 3.14f;
    int number = 0;
    //強制類型轉換隻是臨時改變變量flt的值,其本質是讀取flt的值,而後強制轉換爲int類型的值
    number = (float)flt;
    //number =3
    printf("number = %d", number);
    // flt=3.14
    printf("flt = %f", flt);

    system("pause");
    return 0;
}

在使用printf函數打印輸出變量值時,不會進行自動類型轉換,若是想要獲取預期的結果,須要使用強制類型轉換實現。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* printf()函數與強制類型轉換 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    //由於printf函數不會進行類型轉換,因此這裏獲得一個錯誤的結果
    printf("%d\n", 12.1);
    //12.1爲浮點類型,這裏使用強制類型轉換實現轉換爲整數
    printf("%d\n", (int)12.1);
    printf("%f\n", 10); //整數按照浮點數解析,獲得的結果就是0.000000
    printf("%f\n", (float)10); //強制類型轉換
    system("pause");
    return 0;
}

3.5.3 數據類型轉換案例

類型轉換案例:實現對小數點後三位實現四捨五入

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 實現對小數點後三位實現四捨五入 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    printf("請輸入四捨五入的三位小數\n");
    double input = 0.0;
    scanf("%lf", &input);
    double val = 1.235;
    //1.234*100=123.4 123.4+0.5=123 123/100.0=1.23

    // 1.235*100=123.5 123.5+0.5=124 124/100=1.24
    // 1.24>1.235
    // 1.24-1.235=0.05
    //1.235+0.05=1.24
    double result = (int)(input * 100 + 0.5) / 100.0;
    printf("result =%.2f", result);
    system("pause");
    return 0;
}

類型轉換案例:帳戶餘額的分大於4分就偷錢

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 帳戶餘額的分大於4分就偷錢 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/11/05 */
int main(int argc, char* argv[]) {
    printf("請輸入你的帳戶餘額\n");
    double balance = 0.0;
    scanf("%lf", &balance);

    // 12.34*10=123.4 123.4+0.6=124 124/10.0=12.4 12.4>12.34
    double rest = (int)((balance * 10) + 0.6) / 10.0;
    printf("rest = %f", rest);
    if (rest < balance) {
        //
        printf("能夠偷錢%.2f元", balance - rest);
    }

    system("pause");
    return 0;
}
相關文章
相關標籤/搜索