数据类型(二)及编码

数据类型(二)及编码



1. char类型

1.1 基础信息

  • 名称:字符型。

  • 单位:一个字节(8 bit位)。

  • 格式匹配符:

    • 数值型:
      • 有符号:%hhd —— char 显示数值专用格式匹配符。
      • 无符号:%hhu —— unsigned char 显示数值专用格式匹配符。
    • 字符型:
      • %c
  • 取值范围:

    • 有符号: -128 ~ 127
    • 无符号:0 ~ 255
  • 程序获取

    #include <stdio.h>
    #include <limits.h>
    
    int main(void)
    {
    	// 获取无符号数取值范围
    	printf("char 无符号 min = 0,max = %hhu\n", UCHAR_MAX);
    	// 获取有符号数取值范围
    	printf("char 有符号 min = %hhd,max = %hhd\n", CHAR_MIN, CHAR_MAX);
    	// 获取 char 占用的字节数
    	printf("char 大小 = %u\n", sizeof(char));
    	// 获取 unsigned char 占用的字节数
    	printf("unsigned char 大小 = %u\n", sizeof(unsigned char));
    
    	return 0;
    }
    
    

在这里插入图片描述

2. ASCII码

2.1基本信息

  • char 类型数据,数值 对应一个 ASCII 码。
  • ASCII表:

在这里插入图片描述

#include <stdio.h>

int main(void)
{
	char ch = 'A';  // 定义变量 ch, 指定初值为 'A';

	printf("ch = %c\n", ch);  // c: character  %c 用来显示字符的 格式匹配符。

	ch = 'm';	// 给变量ch 赋值成 'm', 覆盖 原来的 'A';

	printf("ch = %c\n", ch);

	ch = 97;	// 使用 范围内的数值 97 ,给 ch 赋值。

	printf("ch = %c\n", ch);  // 将数值97,按照字符格式打印输出。

	ch = 98;	// 使用 范围内的数值 98 ,给 ch 赋值。

	printf("ch = %c\n", ch);  // 将数值98,按照字符格式打印输出。

	return 0;
}

2.2 练习:

  • 将 大写字母,转换成 小写字母。
#include <stdio.h>

int main(void)
{
	char ch = 'R';  // char 变量定义

	printf("R 转换的小写为:%c\n", ch+32);  //ch+32 表达式,对应格式匹配符 %c

	char ch2 = 'h'; // char 变量定义

	printf("h 转换的大写为:%c\n", ch2-32); //ch2-32 表达式,对应格式匹配符 %c

	char ch3 = '5'; 
	// 借助字符5, 利用 ASCII特性,打印出 字符9
	printf(" 打印字符9 = %c\n", ch3+4);

	return 0;
}

2.3 ASCII表说明

  • 0 ~ 32 ASCII码 对应的字符都不可见。
  • 常用的 ASCII码:
    • ‘a’:ASCII码值 97
    • ‘A’:ASCII码值 65
    • ‘0’:ASCII码值 48
    • ‘\n’ ASCII码值 10
    • ‘\t’ 制表符。tab键对应的字符。(ASCII码值 9)
    • ‘\0’ ASCII码值 0

在这里插入图片描述

2.4 练习:

  • 在一个printf函数中, 打印输出 hello 换行 world 换行
// 方法1
int main(void)
{
	printf("hello\nworld\n");

	return 0;
}
// 方法2
int main(void)
{
	char ch = '\n';  //定义ch变量,初值为'\n'

	printf("hello%cworld%c", ch, ch); // 等价于 printf("hello\nworld\n");

	return 0;
}
方法3
int main(void)
{
	char ch = 10;  //定义ch变量,初值为'\n'

	printf("hello%cworld%c", ch, ch); // 等价于 printf("hello\nworld\n");

	return 0;
}  
  • 一个printf中打印 hello (一个tab缩进) world 换行
int main(void)
{
	char ch1 = '\t';  // 实现 一个tab缩进
    char ch2 = '\n';  // 实现 一个换行。
   
	printf("hello%cworld%c", ch1, ch2); 

	return 0;
}

3. 转义字符

3.1 基本信息

  • ‘/’: 自右向左划, 叫做 “斜杠”。
  • ‘\’ : 自左向右划,叫做 “反斜杠” 。 ——是 转义字符。
  • 转义字符的作用:
    1. 将普通字符,转换为 特殊意。
      1. 如: ‘\n’ : 这是一个字符。代表换行。
      2. 如:‘\t’ : 这是一个字符。代表 一个制表符。
    2. 将特殊字符,还原成本身意。
      1. 如:\\n : 这样就将 一个字符 ‘\n’,还原成 两个字符:‘\’ 和 ‘n’

3.2 练习

  • 将 特殊字符转换成本身意。

题目:屏幕上严格输出 如下内容:【 ‘\n’ 的值是 10】 要求显示时要有 ‘ ’

int main(void)
{
	printf("'\\n'的值是 %hhd", '\n');

	return 0;
}

在这里插入图片描述

4.实型(浮点型)

4.1 基础信息

  • 显示小数。

  • float : 单精度浮点型。 %f 大小:4字节。( 可以使用 sizeof() 求取 )

    • float = 4.35 默认会被编译器理解为 double 类型。
    • float v = 4.567f; 编译器理解 float。
    • %f 格式匹配符,默认保留6位小数。
  • double: 双精度浮点型。%lf 大小:8字节。

    • double d = 5.68;

4.2 取值范围

  • 使用头文件 #include <float.h> 获取浮点型取值范围。
int main(void)
{
	printf("float 范围:%f ~ %f\n", FLT_MIN, FLT_MAX);

	printf("double 范围:%lf ~ %lf\n", DBL_MIN, DBL_MAX);

	return 0;
}
  • 求取的结果:

在这里插入图片描述

4.3 精度问题

  • float类型:
    • 精度 6~7 位:
      • 整数部分 + 小数部分 <= 6 位, 准确。
      • 整数部分 + 小数部分 == 7 位,可能准确,也可能不准确。
      • 整数部分 + 小数部分 > 7位。不准确。
  • double类型
    • 精度 15~16 位:
      • 整数部分 + 小数部分 <= 15 位, 准确。
      • 整数部分 + 小数部分 == 16 位,可能准确,也可能不准确。
      • 整数部分 + 小数部分 > 16位。不准确。

在这里插入图片描述

  • 不同平台(操作系统),对应float、double 类型实现的精度有可能不同。以上是Windows 下 特性。

  • float 和 double 不存在 “无符号”类型。

5. bool 类型

  • C语言原来没有 bool 类型。 C99标准中,新增了 bool 类型。C++ 自带 bool类型。
  • 用处:
    • 表示 :
      • 好、坏
      • 真、假
      • 对、错
      • 是、否
    • 取值:
      • true —— 真 —— 1
      • false —— 假 —— 0
  • C语言使用bool 的条件:
    • 编译器要支持c99标准。
    • 导入 #include <stdio.h>
  • bool 类型的大小。
    • 1字节。 ( sizeof() 求取 )
  • bool 没有专用的格式匹配符。 打印时,使用 %d 来打印。
    • true —— 真 —— 1
    • false —— 假 —— 0
int main(void)
{
	bool aa = true;  // 定义bool 类型变量 aa , 初值为 true == 1

	printf("aa = %d\n", aa);

	aa = false;  // 给 bool 类型变量 aa 赋值为 false == 0

	printf("aa = %d\n", aa);

	return 0;
}

6. 进制和转换

  • 计算机 只 使用 2 机制。
  • 8进制、10进制、16进制。统统都是给人类用的!!!

6.1 存储知识

  • 1 bit位 就是一个 二进制位。 存 0 或 1
  • 一个字节(Byte) 1B = 8bit位。
  • “内存单元” 是计算机内存存储的最小单位, 一个内存单元 == 1字节。
  • 1KB = 1024B
  • 1MB = 1024KB
  • 1GB = 1024MB
  • 1TB = 1024GB

6.2 二进制

  • 取值 1 或 0. 逢 2进 1。 借 1 当 2 。

  • 没有格式匹配符

6.2.1 十进制 转 二进制

  • 除 2 反向取余法

在这里插入图片描述

6.2.2 二进制转十进制

  • 掌握 20 ~ 210 各自的取值:

    • 20 : 1
    • 21 : 2
    • 22 : 4
    • 23 : 8
    • 24 : 16
    • 25 : 32
    • 26 : 64
    • 27 : 128
    • 28 : 256
    • 29 : 512
    • 210 : 1024
  • 计算方法,对应二进制位,有1 累加2的指数次幂值,有 0 略过。

在这里插入图片描述

  • 11101 —— 29
  • 10110 —— 2+4+16 = 22

6.3 八进制

  • 逢 8 进 1。 借1当8。
  • 取值: 0/1/2/3/4/5/6/7 最大值 7
  • 格式匹配符:%o 和 %#o(带#的输出时十六进制数字前带有0)
  • 表示语法: 0开头 。
  • 8 进制 ——> 10 进制:
    • 056 == 80 * 6 + 81 * 5 = 6 + 40 = 46
    • 0123 = 80 * 3 + 81 * 2 + 82 * 1 = 3 + 16 + 64 = 83
  • 10 进制 ——> 8进制:
    • 除 8 反向取余法
      • 135 —— 0207

6.3.1 八进制转二进制

  • 转换算法: 将 8进制数,自左向右,每一位,用 421 码 展开。
  • 练习:
    • 056 —— 101110
    • 04735 —— 1001 1101 1101
    • 053261 —— 101 0110 1011 0001

详细剖析:如056中,5是由421中的一个4一个1组成,也就是说421这三个数字的个数为1、0、1组成了5,那么5就是101。6是由421中的一个4一个2组成,也就是说421这三个数字的个数为1、1、0组成了6,那么6就是110。所以056的八进制=101110的二进制。

6.3.2 二进制转八进制

  • 转换方法:自右向左,每3个二级制位一组, 不足3位补0 。

    • 1101010101111010

      • 分组:1 101 010 101 111 010
      • 补齐:001 101 010 101 111 010
      • 八进制数为:0152572
    • 10110111011

      • 分组:10 110 111 011
      • 补齐:010 110 111 011
      • 八进制数为:02673

6.4 十六进制

  • 逢 16 进 1。 借1当16。
  • 取值: 0~9 10-A/a 11-B/b 12-C/c 13-D/d 14-E/e 15-F/f 最大值: F/f
  • 格式匹配符:%x 或 %#x(带#的输出时十六进制数字前带有0x)
  • 表示语法: 0x开头 。
  • 16 进制 ——> 10 进制:
    • 将每一个16进制位,展开 相加得 10进制。
  • 10 进制 ——> 16进制:
    • 除 16 反向取余法
      • 37:0x25
      • 43:0x2B

6.4.1 十六进制转二进制

  • 转换算法: 将 16 进制数,自左向右,每一位,用 8421 码 展开
    • 0xFAC12 : 1111 1010 1100 0001 0010

详细剖析:F是15,他是由8421中的一个8一个4一个 2一个1组成,即1111,A是10,是由8421中1个8一个2组成,所以是1010,

6.4.2 二进制转十六进制

  • 转换方法:自右向左,每4个二级制位一组, 不足4位补0 。
    • 101001011101011001
      • 分组:10 1001 0111 0101 1001
      • 补齐:0010 1001 0111 0101 1001
      • 16进制数为:0x29759
    • 1110110100111101
      • 分组:1110 1101 0011 1101
      • 补齐:1110 1101 0011 1101
      • 16进制数为:0xED3D

6.5 小结

  • 使用频率最高的是 10 进制。 次高的:16进制。
    • int m = 0x15F4;
    • int n = 0345;
    • int k = 0101101;
      • 不能直接将变量值赋值为 2进制。
      • 上述的赋值,会被编译器理解为 8进制数。
#include <stdio.h>

int main(void)
{
	int a = 56;  // 10进制数作a变量初始化。 —— 定义。

	printf("10进制:a = %d\n", a);
	printf("8进制:a = %o\n", a);
	printf("8进制:a = %#o\n", a);	//在%和x中间添加#,可以在输出时,显示8进制前缀。
	printf("16进制:a = %x\n", a);
	printf("16进制:a = %#x\n", a);  //在%和x中间添加#,可以在输出时,显示16进制前缀。

	return 0;
}

7. 常用的格式匹配符

  • %d
  • %c
  • %x
  • %u
  • %s (后续课程讲,打印字符串)
  • %o
  • %#o
  • %#x
  • %hhd
  • %hd
  • %ld
  • %lld
  • %hhu
  • %hu
  • %lu
  • %llu
  • %f
  • %lf

8. 编码和存储

8.1 无符号存储

unsigned int a = 12;  // 占用 4 字节 32 个 bit位存储。
空间:00000000 00000000 00000000 00000000  ———— 4 字节。
存储:00000000 00000000 00000000 00001100
    
unsigned short b = 15;  //占用 2 字节 16 个 bit位存储。 
空间:00000000 00000000   ———— 2 字节。
存储:00000000 00001111

8.2 有符号存储

  • 需要拿出一个二进制位,专门存储符号。标识正、负。
    • 选用 最高位 为符号位。
    • 正:0
    • 负:1

8.2.1 有符号正数

// 采用 “源码” 存储
int a = 5;
空间:0 0000000 00000000 00000000 00000000
存储:0 0000000 00000000 00000000 00000101   --- 表示存储正数 5

8.2.3 有符号负数

  • 有符号的负数,采用 “补码” 存储
    • 源码:数值的二进制位直接存储。
    • 反码:符号位不变,将其余数值为取反。
    • 补码:反码+1。
int b = -33;
空间:0 0000000 00000000 00000000 00000000
源码:1 0000000 00000000 00000000 00100001
反码:1 1111111 11111111 11111111 11011110   
补码:1 1111111 11111111 11111111 11011111  —— 负33 在计算机中实际的存储形式。 
  • 小结:

    • int —— 4字节 —— 32bit位
      • 有符号:31个数值位。 取值范围 -231 ~ 231 -1 ——> -2147483648 ~ +2147483647
      • 无符号:32个数值位。取值范围 0 ~ 232 -1 ——> 0 ~ 4294967295
    • short —— 2字节 —— 16bit位
      • 有符号:15个数值位。 取值范围 -215 ~ 215 -1 ——> -32768~32767
      • 无符号:16个数值位。取值范围 0 ~ 216 -1 ——> 0 ~ 65535
  • 因此,知道数据类型占用内存的大小,就能算出该类型 无符号数、有符号数 对应的取值范围。

诚挚感谢传智播客王飞老师的讲解以及提供的素材。

发布了4 篇原创文章 · 获赞 0 · 访问量 78

猜你喜欢

转载自blog.csdn.net/Dylan_Cai/article/details/105083843