C语言核心技术-基本数据类型及其应用

C语言核心技术-基本数据类型及其应用

3.1 整数

3.1.1 整数常量

C语言整数常量可以使用u后缀表示位无符号整数,使用l后缀表示long类型的整数,使用ll后缀表示为long long类型的整数

#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 
",100);
    printf("无符号整数常量%d 
",100u);

    printf("有符号长整数常量%ld 
", 2147483647L);
    printf("无符号长整数常量%lu 
", 2147483647UL);

    printf("有符号长长整数常量%lld 
", 9223372036854775807LL);
    printf("无符号长长整数常量%lld 
",  9223372036854775807ULL);
    system("pause");
    return 0;
}

3.1.2 整数的三种进制类型

C语言中的整型常量支持八进制、十进制和十六进制三种进制类型,不支持二进制。

  • 八进制由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
",number);
    //不同进制的输出不会修改数据,只是数据的表现形式发生了变化。
    printf("100以十进制输出的结果是%d
", number);
    //# 表示将进制的完整表现形式输出 例如十六进制的值是以0x开头,八进制的值是以0开头
    printf("100以十六进制输出的结果是%#x
", number);

    system("pause");
    return 0;
}

3.1.3 跨平台的整数

为了解决不同平台,相同的类型占据的大小不一致的问题,C语言标准委员会在C99标准中提出了跨平台的整数,在<stdint.h>头文件中定义,意味着同样的类型在不同的系统下的大小是一致的。
例如int64_t在所有实现C99标准的编译器下占据的都是8个字节,int32_t在所有实现C99标准的编译器下占据的都是4个字节。

#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
", sizeof(val));

    //在不同的平台下占据都是32字节
    int32_t int_32_MAX_VALUE = INT32_MAX;
    printf("sizeof(int_32_MAX_VALUE ) = %d
", sizeof(int_32_MAX_VALUE));
    printf("int_32_MAX_VALUE  = %d
", int_32_MAX_VALUE);


    //在不同的平台下占据都是64字节
    int64_t int_64_MAX_VALUE = INT64_MAX;
    printf("sizeof(int_64_MAX_VALUE ) = %d
", sizeof(int_64_MAX_VALUE));
    printf("int_64_MAX_VALUE  = %lld
", 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	short能存储的最小值是%d,占据的字节数量是%d


", SHRT_MAX, SHRT_MIN, sizeof(short));
    printf("unsigned short能存储的最大值是%d

", USHRT_MAX);
    //32位和64位系统 int和long是等价的
    printf("int能存储的最大值是%d	int能存储的最小值是%d,占据的字节数量是%d

", INT_MAX, INT_MIN, sizeof(int));
    printf("unsigned int能存储的最大值是%u

", UINT_MAX);
    //无符号的整数 最小值都是0 即不能表示负数
    printf("long能存储的最大值是%d	long能存储的最小值是%d,占据的字节数量是%d

", LONG_MAX, LONG_MIN, sizeof(long));
    printf("long long能存储的最大值是%lld	long long能存储的最小值是%lld,占据的字节数量是%d

", LLONG_MAX, LLONG_MIN, sizeof(long long));
    printf("unsigned long long 能存储的最大值是%llu
", 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
", 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
", 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
", 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个字节。

浮点数的常量可以使用十进制的小数和科学计数法表示,科学计数法可以存储特大或者特小的数字

#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
", sizeof(3.14));
    //如果以f结尾的就是float类型
    printf("浮点数3.14f占据的字节数量是%d
", 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 
", flt);
    printf("db1 = %f 	 db2 = %f
", 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 
", flt);
    flt = 0.0f;
    printf("flt = %f 
", flt);

    double dbl = 5.67;
    //printf()默认输出小数后6位数
    printf("dbl = %lf 
", dbl);
    //如果只要输出小数点后2位数,可以使用格式符 %.2lf 实现
    printf("dbl = %.2lf 
", dbl);

    //请输入一个浮点数
    printf("请输入一个浮点数
");
    scanf("%lf", &dbl);
    //输出结果为保留小数点后两位
    printf("你输入的浮点数是%.2lf 
", 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
", sizeof(float));
    printf("float能存储的最大值是%e	 float能存储的最小值是%e 
", FLT_MAX, FLT_MIN);
    printf("
");
    printf("double占据的字节数量是%d 
 ", sizeof(double));
    printf("double能存储的最大值是%e	 double能存储的最小值是%e 
", DBL_MAX, DBL_MIN);
    printf("
");
    printf("long double占据的字节数量是%d
", sizeof(long double));
    printf("long double 能存储的最大值是%e	 long ouble能存储的最小值是%e 
", 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
", (flt1 == flt2)); // 输出结果1表示相等 0则表示不相等

    //double精确的有效位数是15-16位,这里也超出了有效数字,计算不够正确 
    double db1 = 1.00000000000000000000000000000001;
    double db2 = 1.000000000000000000000000000000000000000000000000000000000000000000000000000000001;

    printf(" db1 == db2 ? %d
", (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
", year, ch_gdp);
        printf("%d年美国的GDP是%f
", 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
", 'a');
    printf("char占据的字节数量是%d
", 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 
", 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("
");
    printf("c = %c 
", 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 
", ch);
    printf("字符变量%c对应的整数是%d 
", ch, ch);
    printf("char占据的字节大小是 %u 
", 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
", ch, ch);
    ch = 'a';
    printf("字符%c对应的整数是%d
", ch, ch);
    ch = 'A';
    printf("字符%c对应的整数是%d
", ch, ch);

    int number = 97;
    printf("数字%d对应的字符是%c
", number, number);
    number = 65;
    printf("数字%d对应的字符是%c
", number, number);
    number = 48;
    printf("数字%d对应的字符是%c
", number, number);
    system("pause");
    return 0;
}

3.3.3 转义字符

一些特殊的符号无法直接显示时,我们使用特殊字符来表示。
例如a表示发声,无法在终端上直接显示。
在日常开发中还会使用到各种常用的转义字符,例如 实现tab的效果。
转义字符 实现换行的效果,转义字符实现路径转义。
%%输出百分号。
转义字符还可以使用八进制和十六进制表示,用于表示字符对应的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');
    //日常开发中常用的转移字符 
实现换行
    printf("hello 
");
    printf("world 
");
    // 	 实现tab效果
    printf("C	语	言	核	心	编	程
");
    // 
 实现光标移到行首 由于光标移到行首,最终只会输出C语言核心编程
    printf("CPrimerPlus%cC语言核心编程
", '
');
    //路径转义 \表示路径转义 
    //使用system函数使用电脑上的微信,调用成功的前提条件是电脑上安装了微信
    system(""C:\Program Files (x86)\Tencent\WeChat\WeChat.exe"");
    // %%实现输出百分号
    printf("合格率为%%%d
", 90);

    //八进制转义和十六进制转义
    //八进制的62转换为十进制是50,50表示字符2
    char ch = '62';
    printf("八进制的转义字符62转换为字符的结果是%c 
", ch);//2
    //十六进制的62转换为十进制是98,98表示的字符是b
    ch = 'x62';
    printf("十六进制的转义字符62转换为字符的结果是%c
", 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 
", lower_ch, upper_ch);


    //大写转小写
    upper_ch = 'A';
    lower_ch = upper_ch + 32;
    printf("大写字母%c转换为小写字母的结果是%c 
", 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
", sizeof(flag));
    //成立的结果为1
    printf("bool = %d
", flag);

    flag = false;
    //不成立的结果为0
    printf("bool = %d
", flag);


    //bool在if/else结构和关系运算的使用
    int age = 20;
    bool isAdult = age > 18;
    if (isAdult == 1) {
        printf("你成年了
");
    }
    else {
        printf("你没有成年
");
    }
    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
", sizeof(1.0));
    //ch+1自动转换为int类型,因此占据四个字节
    printf("字符变量ch+1的字节数量是%d
", sizeof(ch + 1));
    printf("字符变量ch+1.0的字节数量是%d
", 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
", number1);
    int result = number1 + number2;

    //使用三目运算和算术运算输出表达式number1+number2大于0还是小于0
    //因为number1按照无符号的结果是4294967286 因此结果是大于0
    number1 + number2 > 0 ? printf("number1 + number2 > 0 
") : printf("number1 + number2 < 0 
");
    printf("按照有符号整数输出 result = %d 
", result);
    printf("按照无符号整数输出 result = %u 
", 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
", num);
    num = (int)(fl + flt);//21 先把fl和flt相加后,强制转换为int
    printf("num =%d
", 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
", 12.1);
    //12.1为浮点类型,这里使用强制类型转换实现转换为整数
    printf("%d
", (int)12.1);
    printf("%f
", 10); //整数按照浮点数解析,得到的结果就是0.000000
    printf("%f
", (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("请输入四舍五入的三位小数
");
    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("请输入你的账户余额
");
    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;
}
原文地址:https://www.cnblogs.com/ittimeline/p/11799443.html