C语言总结深入理解内存中数据的使用-创新互联

你好哇,我是单字鹏。欢迎进入我的C语言总结。

成都创新互联公司专业为企业提供大洼网站建设、大洼做网站、大洼网站设计、大洼网站制作等企业网站建设、网页设计与制作、大洼企业网站模板建站服务,十多年大洼做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。

前面我们总结了数据是如何通过类型变量保存在内存中的,今天我们来总结梳理数据是如何从内存中拿出来的。

先来看看这样一段代码

#include#includevoid* test()
{
	void* pt = malloc(4);
	*((float*)pt) = 9.0;
	return pt;
}
int main()
{
	short* ch = test();
	int* in = (int*)ch;
	float* fl = (float*)in;
	printf("%p %p %p\n", ch, in, fl);
	printf("%d %d %f\n", *ch, *in, *fl);
	return 0;
}

为什么是这样的结果了 ?

不妨用已有的知识来分析看看

总结数据通过类型来访问内存保存数据,也可以控制类型来读取内存的数据。

不同类型的转换

隐式类型转化

C 的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为 整型 提升 。 整型提升的意义 : 表达式的整型运算要在 CPU 的相应运算器件内执行, CPU 内整型运算器 (ALU) 的操作数的字节长度 一般就是 int 的字节长度,同时也是 CPU 的通用寄存器的长度。 因此,即使两个 char 类型的相加,在 CPU 执行时实际上也要先转换为 CPU 内整型操作数的标准长度。 通用 CPU ( general-purpose CPU )是难以直接实现两个 8 比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于 int 长度的整型值,都必须先转 换为 int 或 unsigned int ,然后才能送入 CPU 去执行运算。 char a , b , c ; ... a = b + c ; b 和 c的值被提升为普通整型,然后再执行加法运算。 加法运算完成之后,结果将被截断,然后再存储于a中。 整形提升的方式 有符号的char 和short 是正整数时 因为 为有符号的 所以整形提升的时候,高位补充符号位,即为0 有符号的char 和short 是负整数时

因为为有符号的 所以整形提升的时候,高位补充符号位,即为1

无符号的char 和short 因为符号位为有效数位 没有负数,直接补零。

int main()
{
 char a = 0xb6;
 short b = 0xb600;
 int c = 0xb6000000;
 if(a==0xb6)
 printf("a");
 if(b==0xb600)
 printf("b");
 if(c==0xb6000000)
 printf("c");
 return 0;
}

结果打印的是c。这是为什么了?

因为在cpu的内部的寄存器是4字节的大小,所以在读取内存中的值时会产生一个临时的变量,a,b就会整形提升之后就不是0xb6/0xb600了 因为符号位是1 会以1补齐。0xb6/0xb600是常量默认是int类型就是正整数。

int main()
{
	unsigned char a = 0xb6;
	unsigned short b = 0xb600;
	int c = 0xb6000000;
	if (a == 0xb6)
		printf("a");
	if (b == 0xb600)
		printf("b");
	if (c == 0xb6000000)
		printf("c");
	return 0;
}

这里的结果又是啥?

int main()
{
 char c = 1;
 printf("%u\n", sizeof(c));
 printf("%u\n", sizeof(+c));
 printf("%u\n", sizeof(-c));
 return 0;
}

sizeof(c)计算的是c变量内存空间的大小 而sizeof(+c)/sizeof(-c) 中间产生计算 就会临时的变量就是4个字节 

cpu计算好的值又是如何给char short 赋值的

直接去掉多余的字节赋值给变量 截断

算术转换 如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类 型,否则操作就无法进行。下面的层次体系称为 寻常算术转换 。 long double double float unsigned long int long int unsigned int int 如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。 但是算术转换要合理,要不然会有一些潜在的问题。 float f = 3.14 ; int num = f ; // 隐式转换,会有精度丢失

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


网站名称:C语言总结深入理解内存中数据的使用-创新互联
文章地址:http://ybzwz.com/article/deohds.html