IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言 (整型)数据的存储 -> 正文阅读

[C++知识库]C语言 (整型)数据的存储

一、数据类型介绍

前面我们已经学习了基本的内置类型:

char   //字符数据类型
short   //短整型
int   //整型
long   //长整型
long long   //更长的整型
float   //单精度浮点型
double   //双精度浮点型

以及它们所占用存储空间的大小。

类型的意义:

  1. 使用这个类型,则开辟规定大小的存储空间。
  2. 存储空间在内存中的定位。

二、类型的基本归类

整型家族:

char
	unsigned char //无符号char类型
	signed char
	
short
	unsigned short [int]
	signed short [int]
	
int
	unsigned int
	signed int
	
long
	unsigned long [int]
	signed long [int]

浮点数家族:

	float
	double

构造类型:

	数组类型
	结构体类型 struct
	枚举类型 enum
	联合类型 union

指针类型:

	int *pi;
	char *pc;
	float* pf;
	void* pv;

空类型:

	void 表示空类型
	通常应用于函数的返回类型、函数的参数、指针类型。

三、整型在内存中的存储

一个变量的创建是需要在内存中开辟空间存储的。
空间的大小是根据不同的类型而决定。

接下来我们谈谈数据是如何存储的
eg:

	int a = 20;
	int b = -10;

我们都知道 int 为 a 分配四个字节的空间。那么要如何存储?

3.1 原码、反码、补码

  1. 计算机中有符号数有三种表示方式,即原码、反码、补码。
  2. 三种表示方式均有符号位数值位两部分,符号位使用0表示“正”,用1表示“负”;而数值位三种表示方法各不相同。
  3. 原码:直接将数据翻译成二进制就可以。
  4. 反码:原码的符号位不变,其它位依次取反即可。
  5. 补码:反码+1可得到补码。
  6. 正数的原码、反码、补码都相同。

3.2 对于整型来说,数据在内存中存储的格式是补码。

为什么呢?

在计算机系统中,数值一律用补码来表示和存储。

原因是,使用补码可以将符号位和数值域统一处理
同时,加法和减法也可以统一处理(CPU只有加法器)。
补码和原码相互转换,运算过程是相同的,都可以取反加一得到彼此。

我们也可以举个例子来证明:

在计算机中没有减法器,但是我们可以让正数加上负数,来进行减法操作。
	eg:1 + (-1)
	//1 正数原码、反码、补码相同
	//原码:00000000000000000000000000000001
	//反码:00000000000000000000000000000001
	//补码:00000000000000000000000000000001

	//-1
	//原码:10000000000000000000000000000001
	//反码:11111111111111111111111111111110
	//补码:11111111111111111111111111111111

我们观察原码,如果我们使用原码来进行 1+(-1) 会得到什么?
会得到 -2,这明显不是 1+(-1) 的结果。

如果我们使用补码来操作,结果就是 0。

四、大小端介绍

什么是大小端?

大端字节序
把数据的低位字节序的内容存放在高地址处,高位字节序的内容存放在低地址处。

小端字节序
把数据的低位字节序的内容存放在低地址处,高位字节序的内容存放在高地址处。

而数据到底是按照大端还是小端存储,要看编译器的设置。。。

那么如何用段代码来查看编译器是大端还是小端?

我们数值取一,然后取地址存储到指针类型char中。
我们只需要查看指针类型char中的第一个数据,是1则是小端字节序,是0则是大端字节序。
int main() {
	int a = 1;
	char* pi = (char*)&a;
	if (*pi == 1) {
		printf("小端\n");
	}
	else {
		printf("大端\n");
	}
	return 0;
}

也可以写成函数,进行优化…

int check_sys() {
	int a = 1;
	char* p = (char*)&a;
	return *p;
}

int main() {
	int ret = check_sys();
	if (ret == 1) {
		printf("小端\n");
	}
	else {
		printf("大端\n");
	}
	return 0;
}

五、来亿点练习题

①练习题

int main() {
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}

答案:-1, -1, 255
解析
a,b,c 的补码都是一样的 1111 1111。
但是我们看待的不同,a 和 b 首位是符号位,1 表示是负数;而 c 是无符号整型,首位还是数据 1。
最后在输出时,%d是按照 int 形式输出,要整型提升,a 和 b 都是看符号位提升直接补齐 1;而 c 的整型提升因为没有符号位,直接补齐 0。导致最后结果不一样。

int main() {
	char a = -1;	//11111111
	//10000000000000000000000000000001
	//11111111111111111111111111111110
	//11111111111111111111111111111111
	signed char b = -1;	//11111111
	//10000000000000000000000000000001
	//11111111111111111111111111111110
	//11111111111111111111111111111111
	unsigned char c = -1;	//11111111
	//10000000000000000000000000000001
	//11111111111111111111111111111110
	//11111111111111111111111111111111
	printf("a=%d,b=%d,c=%d", a, b, c);
	//整型提升
	//11111111111111111111111111111111 -> a,b
	//00000000000000000000000011111111 -> c
	return 0;
}

②练习题

int main() {
	char a = -128;
	printf("%u\n", a);
	return 0;
}

答案:4294967168
解析

int main() {
	char a = -128;
	//原码:10000000000000000000000010000000
	//反码:11111111111111111111111101111111
	//补码:11111111111111111111111110000000
	//char类型要截断:10000000

	printf("%u\n", a);
	//输出要整型提升,有符号char直接高位补1。
	//补码:11111111111111111111111110000000
	//要以 %u 无符号位方式打印,那么补码形式就是正数
	//正数原码反码补码都一致,系统就直接输出补码。
	return 0;
}

③练习题

int main() {
	char a = 128;
	printf("%u\n", a);
	return 0;
}

答案:4294967168
解析

int main() {
	char a = 128;
	//原码:00000000000000000000000010000000
	//反码:11111111111111111111111101111111
	//补码:11111111111111111111111110000000
	//char类型截断:10000000

	printf("%u\n", a);
	//有符号位整型提升,高位补1.
	//补码:11111111111111111111111110000000
	//%u 以无符号形式输出结果,补码原码一样
	//4294967168
	return 0;
}

char 类型内存存储。
127 再加 1 会变成 -128。
之后的 -127,-126都有迹可循,但是 -128 会复杂一些,需要查看补码反码原码。


④练习题

int main() {
	int i = -20;
	unsigned int j = 10;
	printf("%d\n", i + j);
	return 0;
}

答案:-10
解析

int main() {
	int i = -20;
	//原码:10000000000000000000000000010100
	//反码:11111111111111111111111111101011
	//补码:11111111111111111111111111101100

	unsigned int j = 10;
	//原码:00000000000000000000000000001010
	//补码:00000000000000000000000000001010

	printf("%d\n", i + j);
	//11111111111111111111111111101100
	//00000000000000000000000000001010
	//11111111111111111111111111110110 - 结果补码
	//11111111111111111111111111110101
	//10000000000000000000000000001010 -> -10
	return 0;
}

⑤练习题

int main() {
	unsigned int i;  
	for (i = 9; i >= 0; i--) {
		printf("%u\n", i);
	}
	return 0;
}

答案:死循环
解析

int main() {
	unsigned int i;  //无符号整型,没有负数
	//导致 i 永远大于等于 0
	for (i = 9; i >= 0; i--) {
		//%u 输出无符号整数
		printf("%u\n", i);
	}
	return 0;
}

⑥练习题

int main() {
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++) {
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
	return 0;
}

答案:255
解析

int main() {
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++) {
		//-1 -2...-127 -128 127... 1 0 -1 -2 -3...-127 -128
		a[i] = -1 - i;
	}
	//strlen函数,找到0表示找到\0,\0表示结束
	printf("%d", strlen(a));
	//-1~-128=128
	//1~127=127
	//127+128=255
	return 0;
}

⑦练习题

unsigned char i = 0;
int main() {
	for (i = 0; i <= 255; i++) {
		printf("hello world\n");
	}
	return 0;
}

答案:死循环
解析

unsigned char i = 0;
int main() {
	//无符号char类型,最高范围只能到255
	//始终小于等于255,导致for循环死循环
	for (i = 0; i <= 255; i++) {
		printf("hello world\n");
	}
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:08:08  更:2022-04-01 23:10:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:07:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码