网站建设5000费用预算,网站太花哨,无锡网站建设动态,如何做外贸网站目录
1 数据类型的分类
2 数据存储单位
2.1 位
2.2 字节
2.3 其余单位
3 整数类型
3.1 基本介绍
3.2 整型的类型
3.2.1 整数类型多样性的原因
3.2.2 整型类型之间的相对大小关系
3.3 整型注意事项
3.4 字面量后缀
3.5 格式占位符
3.6 案例#xff1a;声明并输出…目录
1 数据类型的分类
2 数据存储单位
2.1 位
2.2 字节
2.3 其余单位
3 整数类型
3.1 基本介绍
3.2 整型的类型
3.2.1 整数类型多样性的原因
3.2.2 整型类型之间的相对大小关系
3.3 整型注意事项
3.4 字面量后缀
3.5 格式占位符
3.6 案例声明并输出多种字面量整型数据
3.7 案例printf 输出 scanf 输入的多种整型数据
3.8 精确宽度类型
4 浮点类型
4.1 基本介绍
4.2 浮点数的类型
4.3 浮点型注意事项
4.4 浮点型数据的两种表现形式
4.4.1 科学计数法
4.5 字面量后缀
4.6 格式占位符
4.7 案例声明并输出多种字面量浮点型数据
4 字符类型
4.1 基本介绍
4.2 转义字符
4.3 格式占位符
4.4 字符类型本质
4.5 ASCII 码
4.6 案例字符型数据的输出、计算与溢出 4.7 案例字母大小写转换
5 布尔类型
5.1 基本介绍
5.2 声明布尔类型的三种方式
5.2.1 宏定义
5.2.2 _Bool 类型
5.2.3 bool 类型
6 sizeof 获取数据的存储大小
6.1 注意事项
6.2 查看基本数据类型、字面量和变量的大小
7 测试题 1 数据类型的分类 程序的主要目的就是对数据进行计算和处理为了方便数据的管理通常会对数据进行分类。就像根据容器的容量和形状不同可以分成大杯中杯、大碗小碗等不同的容器适合装不同的东西。 C 语言根据数据的特性和用途进行了类型划分不同类型的数据在内存中占据不同大小的空间。 注意字符型 char 也其实可以划分到【基本类型 - 整型】里边。 2 数据存储单位
2.1 位 bitb位计算机中的最小存储单位表示一个二进制位。
2.2 字节 ByteB字节计算机中基本存储单元1 Byte 8 bit。
2.3 其余单位 KilobyteKB千字节是字节的更大单位。1 KB 1024 Bytes注意在计算机科学中KB、MB、GB 等通常使用 2 的幂次方作为定义即 1024而不是传统的 1000。KB 常用于表示文件大小、内存使用量等。 MegabyteMB兆字节是更大的数据存储单位。1 MB 1024 KB。MB 常用于描述较大的文件大小如软件安装包、音乐文件、视频文件等。 GigabyteGB吉字节是更大的数据存储单位。1 GB 1024 MB。GB 常用于描述硬盘驱动器、固态硬盘、USB 闪存盘等的存储容量以及大型软件、高清视频等的文件大小。 TerabyteTB太字节是更大的数据存储单位。1 TB 1024 GB。TB 级别的存储通常用于企业级存储解决方案、数据中心、大型数据库以及个人用户的大量数据备份等。 PetabytePB拍字节是更大的数据存储单位。1 PB 1024 TB。PB 级别的存储通常用于超大规模的数据中心、云计算平台、大数据分析等领域。 ExabyteEB艾字节是更大的数据存储单位。1 EB 1024 PB。EB 级别的存储主要用于超大规模的数据存储需求如全球互联网数据的存储、大型科研项目的数据存储等。 3 整数类型
3.1 基本介绍 整数类型简称整型就是用于存放整数值的比如12345666888999 等。
3.2 整型的类型
类型存储大小值范围 short signed short 2 字节-32,768 (-2^15) 到 32,767 (2^15 - 1)unsigned short2 字节0 到 65,535 (2^16 - 1)int signed int16 位2 字节32 位4 字节16 位-32,768 (- 2^15 ) 到 32,767 (2^15-1)32 位-2,147,483,648 (- 2^31) 到 2,147,483,647 (2^31 -1) unsigned unsigned int 16 位2 字节 32 位4 字节16 位0 到 65,535 (2^16-1) 32 位0 到 4,294,967,295 (2^32 -1)long signed long 32 位4 字节 64 位8 字节 一般同 int 一样的大小 32 位-2,147,483,648 (- 2^31) 到 2,147,483,647 (2^31 - 1) 64 位9223372036854775808(-2^63) 到9223372036854775807 (2^63-1)unsigned long4 字节 或 8 字节32 位0 到 4,294,967,295 (2^32 - 1) 64 位0 ~ 18446744073709551615 (2^64 - 1)long long signed long long8 字节9223372036854775808(-2^63) 到 9223372036854775807 (2^63-1)unsigned long long8 字节0 ~ 18446744073709551615 (2^64 - 1)
3.2.1 整数类型多样性的原因
内存效率: 不同的数据类型占用不同的内存空间。例如short 和 unsigned short 类型仅占用 2 字节比 int 类型通常是 4 字节节省一倍的空间。在资源受限的系统中比如嵌入式设备使用较小的数据类型可以有效减少内存消耗。
性能优化: 处理器通常针对不同大小的数据类型进行了优化。使用与处理器寄存器大小相匹配的数据类型可以提高代码的执行效率。例如在 32 位系统上使用 int 或 unsigned int 可能比使用 long 更快因为 int 的大小与寄存器大小一致。
数值范围: 不同的数据类型可以表示不同的数值范围。例如int 类型通常可以表示从 -2,147,483,648 到 2,147,483,647 的值而 unsigned int 类型可以表示从 0 到 4,294,967,295 的非负数。选择适当的数据类型可以确保程序能够正确地存储和处理所需范围内的数值。
跨平台兼容性: C 语言标准规定了一些类型的基本行为但具体实现如 int, long, long long 的大小可能因平台而异。例如int 在某些系统上可能是 16 位而在其他系统上可能是 32 位。提供多种类型有助于编写可在不同硬件和操作系统上运行的代码。
类型安全: 使用适当的数据类型有助于防止溢出和其他类型错误。例如如果知道一个计数器永远不会超过 65535使用 unsigned short 可以确保不会发生意外的溢出从而增加代码的健壮性和安全性。
代码清晰性: 使用正确的数据类型可以使代码更具可读性。例如使用 unsigned 类型来存储已知为非负的值可以清楚地表达意图使代码更容易理解和维护。
3.2.2 整型类型之间的相对大小关系 C 语言标准定义了不同整数类型之间的相对大小关系但并没有严格规定每个类型的精确位数以便于在不同的硬件平台上保持灵活性和可移植性。 根据 C99 标准整数类型的相对大小关系如下
char 的大小是最小的通常为 1 字节8位。short int 或简写为 short 至少与 char 同样大但通常比 char 大。int 至少与 short 同样大。long int 或简写为 long 至少与 int 同样大。long long int 或简写为 long long 至少与 long 同样大。 尽管 C 标准允许实现有一定程度的灵活性但在 C99 标准中它规定了某些最小值
short 至少是 16 位。int 至少是 16 位。long 至少是 32 位。long long 至少是 64 位。 要确定特定编译器和平台上的确切大小可以使用 sizeof 运算符后文讲解。 提示大多数情况下long 的大小和 int 相同。所以如果需要小的存储空间就用 short正常的就用 int需要大的存储空间就用 long long。 3.3 整型注意事项 各类型存储大小受到操作系统、编译器、硬件平台的影响。 整型分为有符号 signed 和无符号 unsigned 两种默认是 signedsigned 可省略。 开发中使用整型一般用 int 型如果不足以表示大数可以使用 long long。
3.4 字面量后缀 字面量是源代码中一个固定值的表示法用于直接表示数据如图所示 一个整数字面量不加后缀默认是 int 类型。 如果需要表示 long 类型字面量需要添加后缀 l 或 L为了和数字 1 区分开建议使用大写 L。 如果需要表示 long long 类型字面量需要添加后缀 ll 或 LL为了和数字 1 区分开建议使用大写 L。 如果需要表示无符号整数字面量需要添加后缀 u 或 U 注意 u 和 l 可以结合使用不分先后如 ul无符号 long 类型、ULL无符号 long long 类型lu无符号 long 类型 等。 注意如果一个整数字面量没有后缀那么它默认是 int 类型除非它的值太大以至于不能被 int 类型容纳这时它会被视为 long 类型。 3.5 格式占位符 %hd 对应 short 类型%hu 对应 unsigned short 类型。 %d 对应 int 类型%u 对应 unsigned int 类型。 %ld 对应 long 类型%lu 对应 unsigned long 类型。 %lld 对应 long long 类型%llu 对应 unsigned long long 类型。
格式说明符对应的整型类型%hdshort%huunsigned short%dint%uunsigned int%ldlong%luunsigned long%lldlong long%lluunsigned long long 注意在 C99 标准之前%lld 和 %llu 可能不被所有编译器支持因为它们是为 long long 类型引入的而 long long 是在 C99 中标准化的。对于早期的 C 标准可能需要使用编译器特定的扩展或避免使用 long long 类型。 前面提到字面量的后缀 UL 也可以写成 LU不分先后但是在格式占位符中就不可以这样啦要严格遵守顺序 3.6 案例声明并输出多种字面量整型数据
#include stdio.hint main()
{// short 类型short a1 10; // 等同于 signed short a1 10;signed short a2 -10;unsigned short a3 20;printf(short a1%hd; signed short a2%hd; unsigned short a3%hu\n, a1, a2, a3);// 输出short a110; signed short a2-10; unsigned short a320// int 类型int b1 100; // 等同于 signed int b1 100;signed int b2 -100;unsigned int b3 200u;unsigned b4 300U; // 等同于 unsigned int b4 300U;printf(int b1%d; signed int b2%d; unsigned int b3%u; unsigned b4%u\n, b1, b2, b3, b4);// 输出int b1100; signed int b2-100; unsigned int b3200; unsigned b430// long 类型long c1 1000l; // 等同于 signed long c1 1000l;signed long c2 -1000L; // 推荐大写后缀,以此和数字 1 区别unsigned long c3 2000UL; // 推荐大写后缀printf(long c1%ld; signed long c2%ld; unsigned long c3%lu\n, c1, c2, c3);// 输出long c11000; signed long c2-1000; unsigned long c32000// long long 类型C99及以后long long d1 10000ll; // 等同于 signed long long d1 10000ll;signed long long d2 -10000LL; // 推荐大写后缀,以此和数字 1 区别unsigned long long d3 20000ULL; // 推荐大写后缀printf(long long d1%lld; signed long long d2%lld; unsigned long long d3%llu\n, d1, d2, d3);// 输出long long d110000; signed long long d2-10000; unsigned long long d320000return 0;
}
3.7 案例printf 输出 scanf 输入的多种整型数据
#include stdio.hint main()
{short s;unsigned short us;int i;unsigned int ui;long l;unsigned long ul;long long ll;unsigned long long ull;printf(Enter a short integer: );scanf(%hd, s);printf(Enter an unsigned short integer: );scanf(%hu, us);printf(Enter an integer: );scanf(%d, i);printf(Enter an unsigned integer: );scanf(%u, ui);printf(Enter a long integer: );scanf(%ld, l);printf(Enter an unsigned long integer: );scanf(%lu, ul);printf(Enter a long long integer: );scanf(%lld, ll);printf(Enter an unsigned long long integer: );scanf(%llu, ull);// 打印输入的值以验证printf(Values entered:\n);printf(Short: %hd\n, s);printf(Unsigned Short: %hu\n, us);printf(Int: %d\n, i);printf(Unsigned Int: %u\n, ui);printf(Long: %ld\n, l);printf(Unsigned Long: %lu\n, ul);printf(Long Long: %lld\n, ll);printf(Unsigned Long Long: %llu\n, ull);return 0;
} 输出结果 3.8 精确宽度类型 C 语言的整数类型short、int、long在不同计算机上占用的字节宽度可能是不一样的。程序员有时需要精准的字节宽度以提高代码的可移植性尤其是嵌入式开发中使用精确宽度类型可以确保代码在各种平台上的一致性。 标准库的头文件 stdint.h 中定义了一些新的类型别名如下
类型名称含义int8_t8 位有符号整数int16_t16 位有符号整数int32_t32 位有符号整数int64_t64 位有符号整数uint8_t8 位无符号整数uint16_t16 位无符号整数uint32_t32 位无符号整数uint64_t64 位无符号整数 上面这些都是类型别名编译器会指定它们指向的底层类型。比如某个系统中如果 int 类型为 32 位 int32_t 就会指向 int 如果 long 类型为 32 位 int32_t 则会指向 long 。 示例代码
#include stdio.h
#include stdint.hint main()
{// 变量 x32 声明为 int32_t 类型可以保证是 32 位(4 个字节)的宽度。int32_t x32 45933945;printf(x32%d\n, x32); // x3245933945printf(sizeof(x32)%zu\n, sizeof(x32)); // sizeof(x32)4printf(sizeof(int8_t)%zu\n, sizeof(int8_t)); // sizeof(int8_t)1printf(sizeof(int16_t)%zu\n, sizeof(int16_t)); // sizeof(int16_t)2printf(sizeof(int32_t)%zu\n, sizeof(int32_t)); // sizeof(int32_t)4printf(sizeof(int64_t)%zu\n, sizeof(int64_t)); // sizeof(int64_t)8printf(sizeof(uint8_t)%zu\n, sizeof(uint8_t)); // sizeof(uint8_t)1printf(sizeof(uint16_t)%zu\n, sizeof(uint16_t)); // sizeof(uint16_t)2printf(sizeof(uint32_t)%zu\n, sizeof(uint32_t)); // sizeof(uint32_t)4printf(sizeof(uint64_t)%zu\n, sizeof(uint64_t)); // sizeof(uint64_t)8return 0;
} 我们可以通过按住【ctrl 键 鼠标左键单击】的方式查看头文件的源代码 头文件源代码中如下所示 可以看出这段代码定义了一系列类型别名用于表示不同位宽的整数类型。这些别名在跨平台编程中特别有用因为它们提供了一种标准化的方式来指定数据类型的位宽而不需要担心不同平台如 32 位和 64 位系统上基本数据类型如 int、long 等的位宽可能不同的问题。 4 浮点类型
4.1 基本介绍 浮点类型可以表示一个小数比如123.47.80.12 等。
4.2 浮点数的类型 类型 存储大小 值范围 有效小数位数 float 单精度 4 字节 负数-3.4E38 到 -1.18E-38 正数1.18E-38 到 3.4E38 6 ~ 9 double 双精度 8 字节 负数-1.8E308 到 2.23E-308 正数2.23E-308 到 1.8E308 15 ~18 long double 长双精度 32 位10字节 64 位16字节 32位与 double 相同或更大 64位 负数-1.2E4932 到 -3.4E-4932 正数3.4E-4932 到 1.2E4932 18 或更多
4.3 浮点型注意事项 各类型的存储大小和精度受到操作系统、编译器、硬件平台的影响。 浮点数如 float 和 double 类型没有符号unsigned / signed之分。它们可以表示正数、负数和零。浮点数类型的设计初衷就是为了能够存储和表示带有小数部分的数值而这些数值可以是正的、负的或者零。所以不需要也不能在声明浮点数类型的变量时使用 signed 或 unsigned 关键字不然编译器会报错。 4.4 浮点型数据的两种表现形式 十进制数形式如5.12、512.0f、.5120.512 可以省略 0 科学计数法形式如5.12e2、5.12E-2 开发中用到浮点型数字建议使用 double 型如精度要求更高可以使用 long double 型。
4.4.1 科学计数法 小数的指数形式也称为科学记数法是一种用于表示非常大或非常小的浮点数的方法。科学记数法通过将一个浮点数分解为基数mantissa也称为尾数或有效数字和指数exponent两部分来表示。 基数部分 是一个非零的数可以是整数或小数但不能为空至少包含一位有效数字。
指数部分 指数部分由字符 e或 E不区分大小写后跟一个整数组成用于表示基数需要乘以 10 的多少次方来得到原始数值。 指数可以是正数、负数或零。正数指数表示基数需要向右移动小数点相应位数负数指数表示基数需要向左移动小数点相应位数。当指数为正时前面的加号可以省略当指数为负时前面的减号必须明确写出。
总结 字母 e或 E 之前必须有数字且 e或 E后面的指数必须为整数。
正确示例
1e-3 表示 1×10 的 -3 次方即 0.0011.8e-3 表示 1.8×10 的 −3 次方-123e-6 表示 −123×10 的 −6 次方-.1e-3 表示 −0.1×10 的 −3 次方也可以写成 -1e-4
错误示例及原因
e3错误因为 e 前没有数字。2.1e3.5错误因为 e 后面的指数的是小数。.e3错误因为没有有效的数字在 e 之前。e错误没有有效的基数和指数。
4.5 字面量后缀 浮点数字面量不加后缀默认是 double 型。 如果需要表示 float 类型字面量须加后缀 f 或 F。 如果需要表示 long double 类型字面量需加后缀 l 或 L推荐大写 L 以此和数字 1 区分。
4.6 格式占位符 在 C 语言中占位符是一种用于格式化输出的特殊字符通常用于 printf() 等输出函数中用于指定输出的格式和内容。 %f 是浮点类型的格式占位符在 printf 中对应 double 类型float 类型会转换成 double 来处理默认会保留 6 位小数可以指定小数位数如%.2f 表示保留 2 位小数。 %lf 在 printf 中和 %f 意思相同C99 标准加入也对应 double 类型默认保留 6 位小数可以指定小数位数如%.2lf 表示保留 2 位小数。但需要注意的是在 scanf 中 %lf 和 %f 含义不同输入一个 float类型数据时使用 %f而输入 double 类型时必须使用 %lf。 %Lf 对应的是 long double 类型默认保留 6 位小数可以指定小数位数如 %.2Lf 表示保留 2 位小数。需要注意的是输入输出 long double 类型都必须使用 %Lf 占位符。 %e 或 %E 对应科学计数法表示的浮点数可以指定尾数部分所保留的小数位数如 %.2e 表示尾数部分保留 2 位小数。 提示对于 double 类型变量习惯上用 %f 进行输出这样相比 %lf 少打一个字符。 占位符类型用途备注%fdouble或 float在 printf 中用于输出 double 或 float 类型 float 会被提升为 double 处理默认保留 6 位小数在 scanf 中用于输入 float 类型%lfdouble在 printf 中与 %f 相同用于输出 double 类型在 scanf 中必须用于输入 double 类型%Lflong double用于输出和输入 long double 类型默认保留 6 位小数无论输入输出long double 类型都必须使用 %Lf%e 或 %E-用于输出科学计数法表示的浮点数默认尾数保留 6 位小数可以指定尾数部分的小数位数如 %.2e
注意
%f 和 %lf 在 printf 函数中可互换使用因为 printf 会自动处理 float 到 double 的提升。但在 scanf 中它们的使用是有区别的。%Lf 是专门用于 long double 类型的无论是输出还是输入。%e 和 %E 用于输出科学计数法表示的浮点数其中 %E 使用大写字母 E 来表示指数部分。默认情况下这些占位符都只保留 6 位小数但可以通过在 % 和 f、lf、Lf、e 或 E 之间添加 . 和数字来指定小数位数这样得到的结果是四舍五入的形式。有的编译器可能需要使用 %LE 或 %Le 以科学记数法输出但这不是 C 标准规定的慎用
4.7 案例声明并输出多种字面量浮点型数据
#include stdio.hint main()
{// double 类型// 初始化double类型的变量double a1 3.1415; // 标准的 double 类型浮点数double a2 .12345678; // 省略整数部分0的 double 类型浮点数double a3 -2e12; // 使用科学记数法表示的 double 类型浮点数double a4 1.9823e2; // 另一个科学记数法表示的 double 类型浮点数// 使用 %f 和 %lf尽管 %f 通常也用于 double格式化输出// 习惯上就用 %f 输出 double类型这样相比 %lf 少打一个字符printf(a1%f, a2%.10f, a3%.2lf, a4%lf\n, a1, a2, a3, a4);// a13.141500, a20.1234567800, a3-2000000000000.00, a4198.230000// 使用 %e 以科学记数法输出printf(a1%e, a2%.2e, a3%e, a4%e\n, a1, a2, a3, a4);// a13.141500e00, a21.23e-01, a3-2.000000e12, a41.982300e02// float 类型// 初始化 float 类型的变量注意 f/F 后缀表示 float 字面量float f 3.1415; // 不加后缀也行隐式转换 double - floatfloat b1 3.1415f; // float 类型的浮点数float b2 .123456f; // 省略整数部分0的 float 类型浮点数float b3 -2e12F; // 使用科学记数法表示的 float 类型浮点数注意精度损失float b4 1.9823e2F; // 另一个科学记数法表示的 float 类型浮点数// 使用 %f 格式化输出printf(b1%f, b2%f, b3.0%f, b4%f\n, b1, b2, b3, b4);// b13.141500, b20.123456, b3-1999999991808, b4198.229996// 使用 %e 以科学记数法输出printf(b1%e, b2%.2e, b3%e, b4%e\n, b1, b2, b3, b4);// b13.141500e00, b21.23e-01, b3-2.000000e12, b41.982300e02// long double 类型// 初始化 long double 类型的变量注意 l/L 后缀表示 long double 字面量long double c1 3.14159265358979323846L; // long double 类型的浮点数使用 L 后缀如果编译器支持long double c2 .12345678901234567890L; // 省略整数部分0的 long double 类型浮点数long double c3 -2e12L; // 使用科学记数法表示的 long double 类型浮点数long double c4 1.9823e2L; // 另一个科学记数法表示的 long double 类型浮点数// 注意不是所有编译器都支持 L 后缀用于浮点数字面量这里使用 L 主要是为了说明意图// 使用 %Lf 格式化输出 long doubleprintf(c1%Lf, c2%.20Lf, c3%.2Lf, c4%Lf\n, c1, c2, c3, c4);// c13.141593, c20.12345678901234567890, c3-2000000000000.00, c4198.230000// 使用 %Le 或 %LE 以科学记数法输出 long doubleprintf(c1%LE, c2%.2LE, c3%Le, c4%Le\n, c1, c2, c3, c4);// c13.141593E00, c21.23E-01, c3-2.000000e12, c41.982300e02return 0;
} 4 字符类型
4.1 基本介绍 字符类型 char 可以表示单个字符如一个数字、一个字母、一个符号。 char 类型的字面量是用单引号括起来的单个字符。 多个字符称为字符串在 C 语言中使用 char 数组表示数组不是基本数据类型而是构造类型我们后续专门讲解。
4.2 转义字符 可以使用转义字符 \反斜杠 表示特殊含义的字符。 转义字符 说明 \b 退格 \n 换行符 \r 回车符 \t 制表符 \ 双引号 \ 单引号 \\ 反斜杠 如下代码所示
#include stdio.hint main()
{// 使用 \b 退格符printf(Hello\b \bWorld!\n); // 注意这里使用了两个 \b第一个 \b 删除了o第二个 \b 删除了空格所以输出是 HellWorld!// 使用 \n 换行符printf(这是第一行\n这是第二行\n);// 使用 \r 回车符注意在早期的系统中\r\n 通常一起使用表示换行但这里仅展示 \r 的效果printf(使用\r将光标移回行首: Hello World!\n); // 这将输出将光标移回行首: Hello World!因为 \r 将光标移回行首覆盖了“使用”// 使用 \t 制表符printf(姓名\t年龄\t职业\n); // 姓名 年龄 职业printf(张三\t30\t程序员\n); // 张三 30 程序员// 使用 \ 双引号printf(他说:\你好世界\\n); // 他说:你好世界// 直接在双引号里面输入单引号也是可以的printf(字符A的ASCII码是65\n); // 字符A的 ASCII 是 65// 使用 \ 单引号printf(字符\A\的ASCII码是65\n); // 字符A的 ASCII 码是 65// 使用 \\ 反斜杠printf(文件路径是C:\\Users\\Public\\Documents\\file.txt\n); // 文件路径是C:\Users\Public\Documents\file.txtreturn 0;
} 输出结果 4.3 格式占位符 使用 %c 表示 char 类型输出字符。使用 %d 输出对应的 ASCII 码值。
4.4 字符类型本质 C 语言中char 类型本质是一个整数是 ASCII 码中对应的数字存储长度是 1 个字节 char 类型也可以进行数学运算计算时当做整型计算。 字符型同样分为 signed char无符号和 unsigned char有符号其中 signed char 取值范围 -128 ~ 127unsigned char 取值范围 0 ~ 255。默认是否带符号取决于当前运行环境或者一开始就显示的声明符号。 字符型数据在计算中存储和读取的过程 4.5 ASCII 码 ASCIIAmerican Standard Code for Information Interchange码是一种用于表示文本字符的字符编码标准一共规定了128 个字符的编码比如常见的空格 “SPACE” 是 32二进制 0010 0000数字 0 是 48二进制 0011 0000大写的字母 A 是 65二进制 0100 0001大写的字母 a 是 97二进制 0110 0001。 4.6 案例字符型数据的输出、计算与溢出
#include stdio.hint main()
{// char 类型字面量需要使用单引号包裹// 定义并初始化三个 char 类型的变量分别存储字符A、9和制表符\tchar a1 A;char a2 9;char a3 \t;printf(a1%c, a3%c, a2%c \n, a1, a3, a2); // 输出a1A, a3 , a29// char 类型本质上整数可以进行运算// 定义并初始化两个 char 类型的变量一个存储字符 b另一个存储整数 101ASCII 码为echar b1 b;char b2 101;// 输出 b1 的字符形式和整数值printf(%c-%d \n, b1, b1); // 输出b-98// 输出 b2 的字符形式和整数值printf(%c-%d \n, b2, b2); // 输出e-101// 输出 b1 和 b2 的字符相加后的整数值b e 98 101 199printf(%c%c%d \n, b1, b2, b1 b2); // 输出be199// char 类型取值范围// 定义并初始化三个 char 类型的变量分别测试无符号、有符号 char 以及默认 char通常是有符号unsigned char c1 200; // 无符号 char 取值范围 0 ~255200 是有效值signed char c2 200; // 有符号 char 取值范围 -128~127200 会溢出但这里不会报错只是值会被截断或按二进制方式表示char c3 200; // 当前系统char 默认是 signed char同样会溢出// 输出 c1, c2, c3 的值注意它们都是按整数形式输出的printf(c1%d, c2%d, c3%d, c1, c2, c3); // 输出c1200, c2-56, c3-56// 底层原理还是补码// 200 的 32 位二进制是0000 0000 0000 0000 0000 0000 1100 1000// 低八位 1100 1000 赋值给了 c2 和 c3// c2 和 c3 表示有符号类型所以 1100 1000 表示一个负数的补码即 -56return 0;
} 4.7 案例字母大小写转换
#include stdio.hint main()
{char ch A; // 大写字母 Achar lowerCh ch 32; // 将大写转换为小写printf(Original: %c, Lowercase: %c\n, ch, lowerCh);// Original: A, Lowercase: ach a; // 小写字母 achar upperCh ch - 32; // 将小写转换为大写printf(Original: %c, Uppercase: %c\n, ch, upperCh);// Original: a, Uppercase: A// 注意如果 ch 不是字母这种方法会产生非预期的字符// 例如ch 1; // 数字 1char unexpected ch - 32; // 这将产生一个非预期的字符因为1的ASCII值减去32不是有效的打印字符printf(Original: %c, Unexpected: %c\n, ch, unexpected);return 0;
} 输出结果 5 布尔类型
5.1 基本介绍 布尔值用于表示真、假两种状态通常用于逻辑运算和条件判断。
5.2 声明布尔类型的三种方式
5.2.1 宏定义 C89 标准没有定义布尔类型判断真假时以 0 为假非 0 为真 但这种做法不直观我们一般需要借助 C 语言的宏定义。 使用宏定义来表示布尔类型是一种在 C 语言中模拟布尔类型的常见做法因为 C 语言标准在 C99 之前并没有原生的布尔类型。
#include stdio.h// 宏定义部分
// 定义 BOOL 为 int 类型用于表示布尔值真或假
#define BOOL int
// 定义 TRUE 为 1表示真
#define TRUE 1
// 定义 FALSE 为 0表示假
#define FALSE 0int main()
{// 使用整型表示真假两种状态// int isPass 0;// int isOk 1;// 使用宏定义的 BOOL 类型来表示真假两种状态// 这里通过宏定义避免了直接在代码中使用 int 来表示布尔值使得代码更易于理解和维护// 定义一个 BOOL 类型的变量 isPass并使用 FALSE 宏初始化为假BOOL isPass FALSE;// 定义一个 BOOL 类型的变量 isOk并使用 TRUE 宏初始化为真BOOL isOk TRUE;// 输出 isPass 和 isOk 的值printf(isPass%d, isOk%d \n, isPass, isOk); // isPass0, isOk1// 使用 if 语句判断 isPass 的值// 由于 isPass 被初始化为 FALSE即0所以这个条件不满足不会执行大括号内的代码if (isPass){printf(Pass); // 不会执行}// 使用 if 语句判断 isOk 的值// 由于 isOk 被初始化为 TRUE即1所以这个条件满足会执行大括号内的代码if (isOk){printf(Ok); // Ok}return 0;
}
5.2.2 _Bool 类型 C99 标准提供了_Bool 型_Bool 仍是整数类型但与一般整型不同的是_Bool 变量只能赋值为 0 或 1非 0 的值都会被存储为 1。
#include stdio.hint main()
{// 使用 _Bool 类型定义布尔变量// _Bool 是 C99 引入的用于布尔值的类型其值只能是 0 或 1_Bool isPass 0; // 初始化 isPass 为假// 尽管这里尝试将 -4 赋给 isOk但 _Bool 类型会将其隐式转换为 1真// 因为在布尔上下文中任何非 0 值都被视为真_Bool isOk -4;// 打印 isPass 和 isOk 的值但注意这里使用 %d 格式化字符串来打印 _Bool 类型的值// 实际上_Bool 在大多数编译器中是以 int 的形式处理的所以 %d 是可行的但最好使用 %d 对应的布尔版本如果有的话// 然而标准 C 并没有直接为 _Bool 提供特定的格式化字符串所以 %d 是一个常见的做法printf(isPass%d, isOk%d \n, isPass, isOk); // 输出 isPass0, isOk1// 判断 isPass 的值// 由于 isPass 为假0这个条件不满足不会执行大括号内的代码if (isPass){printf(Pass); // 不会执行}// 判断 isOk 的值// 由于 isOk 在这里被隐式转换为真1这个条件满足会执行大括号内的代码if (isOk){printf(Ok); // ok}return 0;
}
5.2.3 bool 类型 C99 标准还提供了一个头文件 stdbool.h 定义了 bool 代表_Booltrue 代表 1false 代表 0。
#include stdio.h // 引入标准输入输出库用于 printf 函数
#include stdbool.h // 引入布尔类型库提供 bool、true 和 false 的定义int main()
{// 使用 bool 类型定义布尔变量// bool 是 C99 及以后版本中定义的布尔类型其值只能是 true 或 falsebool isPass false; // 初始化 isPass 为假bool isOk true; // 初始化 isOk 为真// 使用 printf 函数打印 isPass 和 isOk的值// 注意虽然 bool 类型在 C 中但 printf 的 %d 格式化字符串仍然可以工作因为 bool 在大多数实现中是以 int 的形式处理的// 然而为了代码的清晰性和可移植性建议使用 stdbool.h 中定义的宏来明确转换 bool 类型到 int// 例如printf(isPass%d, isOk%d \n, (int)isPass, (int)isOk);// 但这里为了简单起见直接使用 %dprintf(isPass%d, isOk%d \n, isPass, isOk); // isPass0, isOk1// 使用 if 语句判断 isPass 的值// 由于 isPass 为假false这个条件不满足不会执行大括号内的代码if (isPass){printf(Pass); // 不会执行}// 使用 if 语句判断 isOk 的值// 由于 isOk 为真true这个条件满足会执行大括号内的代码if (isOk){printf(Ok); // Ok}// 程序正常结束return 0;
} 6 sizeof 获取数据的存储大小 使用 sizeof 可以获取数据类型或变量、字面量的存储大小单位是字节。sizeof 返回一个 size_t 类型的无符号整数值格式占位符是 %zu。 size_t 通常是 unsigned int 或 unsigned long 的别名具体是哪个类型的别名由系统和编译器决定。
6.1 注意事项 计算基本数据类型的大小必须使用括号将数据类型关键字包裹起来。 对于字面量和变量sizeof 运算符可以直接作用于它们括号是可选的可以省略括号。 提示习惯上都加上括号看着更直观。 6.2 查看基本数据类型、字面量和变量的大小
#include stdio.hint main()
{// 计算基本数据类型的大小,必须使用括号将数据类型关键字包裹起来// 使用 sizeof 运算符并通过 %zu无符号大小类型格式化字符串打印结果// 注意sizeof 运算符的结果类型为 size_t在 printf 中使用 %zu 是 C99 及以后版本的标准printf(char%zu \n, sizeof(char)); // char1表示 char 类型占用 1 个字节printf(short%zu \n, sizeof(short)); // short2 表示 short 类型占用 2 个字节printf(int%zu \n, sizeof(int)); // int4 但这也可能因编译器和平台而异printf(long%zu \n, sizeof(long)); // long4但这也可能因编译器和平台而异printf(long long%zu \n, sizeof(long long)); // long long8 8表示 long long 类型占用 8 个字节printf(float%zu \n, sizeof(float)); // float4 表示 float 类型占用 4 个字节printf(double%zu \n, sizeof(double)); // double8 表示 double 类型占用 8 个字节printf(long double%zu \n, sizeof(long double)); // long double16 但这也可能因编译器和平台而异printf(\n);// 计算字面量数据的大小// 对于字面量sizeof 运算符可以直接作用于它们括号是可选的,可以省略括号// 字符字面量如a在大多数情况下被视为 int 类型但 sizeof 会返回其实际存储所需的大小// 整数和浮点数字面量的大小取决于它们被解释为的类型printf(%zu \n, sizeof(a)); // 输出为 4因为字符字面量被提升为 intprintf(%zu \n, sizeof(431)); // 输出为 4因为 431 是 int 类型的字面量printf(%zu \n, sizeof 4.31); // 输出为 8因为 4.31 默认为 double 类型的字面量printf(\n);// 计算变量的大小// 对于变量sizeof 运算符同样可以直接作用于它们括号是可选的可以省略括号char a A;int b 90;long long c 100;double d 10.8;printf(a: %zu \n, sizeof(a)); // 输出为1表示 char 变量 a 占用 1 个字节printf(b: %zu \n, sizeof b); // 输出为4表示 int 变量 b 占用 4 个字节printf(c: %zu \n, sizeof(c)); // 输出为8表示 long long 变量 c 占用 8 个字节printf(d: %zu \n, sizeof(d)); // 输出为8表示 double 变量 d 占用 8 个字节return 0;
} 7 测试题 1. 请将下列数据类型按照所占字节多少从小到大排序。 long long、char、int、short 【答案】char、short、int、long long 【解析】char 类型占 1 个字节short 类型占 2 个字节int 类型占 4 个字节long long 类型占 8 个字节。 2. 写出下面代码的运行结果。
#include stdio.h
int main()
{printf(%zu, sizeof(12.5));return 0;
} 【答案】8 【解析】字面量 12.5 会被识别为 double 类型double 类型占 8 个字节。 3. 写出下面代码的运行结果。
#include stdio.h
int main()
{int a 10;_Bool b1 -4;printf(%d, a b1);return 0;
} 【答案】11 【解析】C99 标准提供了_Bool 型_Bool 仍是整数类型但与一般整型不同的是_Bool变量只能赋值为 0 或 1非 0 的值都会被存储为 1。