快上网专注成都网站设计 成都网站制作 成都网站建设
成都网站建设公司服务热线:028-86922220

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

C语言---数据的存储-创新互联

目录

一、数据存储

创新互联于2013年开始,先为高碑店等服务建站,高碑店等地企业,进行企业商务咨询服务。为高碑店企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

二、数据存储类型分类

1、整型家族

2、浮点型家族

3、自定义类型

4、指针类型

5、空类型

三、整型家族在内存中的存储

1、大小端的理解

2、大小端直观内存显示图:

3、大小端存储的方式如何检测

4、整型家族内存中的存储方式

a、原码反码补码:    

b:数据在内存中的存储

四、浮点型家族在内存中的存储

1、IEEE的存储规则

2、浮点数在内存中的存储

五、总结:


一、数据存储

基本数据类型

char            // 字符数据类型           1个字节 short           // 短整型                      2个字节 int               // 整形                          4个字节   long            // 长整型                      4个字节   long long    // 更长的整形               8个字节 float            // 单精度浮点数           4个字节 double        // 双精度浮点数           8个字节   
二、数据存储类型分类 1、整型家族
char :                          取值范围  unsigned char              0~255     signed char              -128~127 short: unsigned short [ int ]      0~65,535     signed short [ int ]      -32768~32,767 int: unsigned int                  0~4,294,967,295     signed int                  -2,147,483,648~2,147,483,647 long: unsigned long [ int ]         0~4,294,967,295     signed long [ int ]        -2,147,483,648~2,147,483,647
2、浮点型家族
float double long double
3、自定义类型
结构体类型                               struct   枚举类型                                   enum 联合类型                                   union
4、指针类型

char*          

short*       int*               long*           long long*    float*           double*  struct* pc  void*  
5、空类型

void     空类型(用于函数的返回类型、函数的参数、指针类型)

三、整型家族在内存中的存储 1、大小端的理解

  数据是从低位向高位进行存储,但在数据的存储过程中,数据在从低位向高位的存放顺序不一,从而形成了两种数据存放的模式:大端模式和小端模式

大端(存储)模式:     是指数据的低位字节内容保存在内存的高地址中,而数据的高位字节内容保存在内存的低地址中; 小端(存储)模式:     是指数据的低位字节内容保存在内存的低地址中,而数据的高位字节内容保存在内存的高地址中。
2、大小端直观内存显示图:

3、大小端存储的方式如何检测

4、整型家族内存中的存储方式

  整型家族在内存中的存储是以补码的方式进行存储,再讲他们的存储之前先讲一下什么是原码反码补码。原码反码补码在32位机上是32比特位,在64机位上是64比特位。

a、原码反码补码:    

  ①原反补码中:第一位符号位,其余几位为数据值位。

②原码反码补码

正数的符号位为0,原码的数值位为该数,原码反码补码相同

负数的符号位为1,原码的数值位为该数,反码符号位不变数值位取反,补码为反码+1

 

  ③该知识为计算机组成原理中的相关知识,原码转换为补码总结为:

正数的原反补码相同,负数符号位不变。

补码为原码从右边数到第一个1位置不变,数值位往左到符号位后全部取反。

b:数据在内存中的存储

  ①实例一

int main()
{
	//整型家族
	//10000000 00000000 00000000 00010100   原码
	//11111111 11111111 11111111 11101100   补码
	//ff ff ff ec
	unsigned int i = -20;
	
	//00000000 00000000 00000000 00001010   原码
	//00000000 00000000 00000000 00001010   补码
	//00 00 00 0a
	int j = 10;
	

	printf("%d\n", i + j);//%d打印的是有符号的数
	//i+j
	// 补码相加
	//11111111 11111111 11111111 11101100   i
	//00000000 00000000 00000000 00001010   j
	//11111111 11111111 11111111 11110110   i+j补码
	//10000000 00000000 00000000 00001010   i+j原码
	//以有符号的形式打印就是补码转为原码(数据在内存中以补码存储,打印有符号数值时转为原码)
	//结果-10

	printf("%u\n", i + j);//%u打印的是无符号的数
	//i+j
	// 补码相加
	//11111111 11111111 11111111 11101100   i
	//00000000 00000000 00000000 00001010   j
	//11111111 11111111 11111111 11110110   i+j补码
	//以无符号的形式打印就是直接打印补码(首元素1不再表示符号位)
	//结果4294967286
    
    return 0;
}

②实例二

int main()
{
    //因为i是无符号数,所以在循环中一直是大于等于0,进入死循环
    unsigned int i;
	for(i = 9; i >= 0; i--)
		printf("%u\n",i);
}

③实例三

int main()
{
    //10000000 00000000 00000000 00000001 原码
	//11111111 11111111 11111111 11111111 补码
	//char类型只取1个字节,内存中存放ff(11111111)
    char a = -1;
	signed char b = -1;
	//a,b是有符号的char,%d输出时会整型提升前面补符号位1
	//11111111 11111111 11111111 11111111
	//转为原码为10000000 00000000 00000000 00000001打印为-1

    unsigned char c = -1;
	//c是无符号char,整型提升前面补0
	//00000000 00000000 00000000 11111111无需转为原码直接打印255
	printf("%d %d %d\n", a, b, c);
    return 0;
}

a,b,c内存中的存放

运行结果

④实例四

int main()
{
    //128
	//00000000 00000000 00000000 10000000  原码
	//00000000 00000000 00000000 10000000  补码
	//存入内存10000000
	char a = 128;

	//-128
	//10000000 00000000 00000000 10000000 原码
	//11111111 11111111 11111111 10000000 补码
	//存入内存10000000
	char b = -128;

	//a整型提升为
	//11111111 11111111 11111111 10000000 补码
	//10000000 00000000 00000000 10000000 转为原码
	//以%d输出原码
	//以%u直接输出补码
	//  
	//b整型提升为
	//11111111 11111111 11111111 10000000 补码
	//10000000 00000000 00000000 10000000 转为原码
	//以%d输出原码
	//以%u直接输出补码
	printf("%d %d\n", a, b);
	printf("%u %u\n", a, b);

    return 0;
}

运行结果

char类型在内存中的存储范围为-128~127,上图中char类型的128存入内存中相当于127+1=-128

⑤实例五

int main()
{ 
   char a[1000];
	int i;
	for (i = 0; i< 1000; i++)
	{
		a[i] = -1 - i;
		//有符号char类型的取值范围是 -128~127
		//-1 -2 -3 -4 ... -128 127 126 ... 1 0
		//128 + 127 = 255
	}
	printf("%d", strlen(a));//'\0'结束
    return 0;
}

运行结果

四、浮点型家族在内存中的存储     1、IEEE的存储规则

在讲浮点型在内存中的存储前首先要了解什么是IEEE规则

IEEE 754 规定:

对于32位的单精度浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。

对于64位的双精度浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

如图所示:     32位:

64位:

根据国际标准IEEE754,任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S * M * 2^E (-1)^S: 表示符号位,当 S=0 , V 为正数;当 S=1 , V 为负数。 M: 表示有效数字,大于等于 1 ,小于 2 。 2^E: 表示指数位。
对于M来说:
IEEE 754 规定,在计算机内部保存 M 时,默认这个数的第一位是1,因此可以被舍去,只保存后面的部分,比如保存1.625时只保存625,取出来时,小数点前自动补1。 这样就可以节省一个比特位,增加精度。 以 32 位浮点数为例,留给M 只有 23位,将第一位的 1 舍去以后,等于可以保存 24 位有效数字,64位浮点数同样如此。
对于E来说:
E是一个无符号的整数 如果 E 为 8 位,它的取值范围为 0~255; 如果 E 为 11 位,它的取值范围为 0~2047 。 但是,我们知道,科学计数法中的E 是可以出现负数的,所以IEEE754 规定,存入内存时 E 的真实值前必须再加上一个中间数。 对于 8 位的 E ,这个中间数是127 ; 对于 11 位的 E ,这个中间数是1023 。 比如, 2^13中 的 E 是 13 ,所以保存成 32 位浮点数时,必须保存成 13+127=140 ,即 10001100 。
但同时我们要考虑到,浮点数无限接近于0或趋于无穷大的情况。
当E为全0时,即真实值为-127( 或者-1023),2^-127(或者 -1023)是一个无限接近于0的数。 当E为全1时,即真实值为128( 或者1024),2^128(或者 1024)是一个趋于无穷大的数。
2、浮点数在内存中的存储
int main()
{
    //浮点型家族
	//9
	//00000000 00000000 00000000 00001001 原码反码补码相同
	int n = 9;
	float* pFloat = (float*)&n;
	//取原码00000000 00000000 00000000 00001001
	//以%d打印为9
	printf("n的值为: %d\n",n);

	//00000000 00000000 00000000 00001001 *pFloat得到的是这个,以%f的形式打印
	//0 00000000 00000000000000000001001
	//S = 0
	//E = 0(E为全0,是一个无限接近于0的数)
	//M = 1.000..
    //(-1)^S * M * 2^E 
    //(-1)^0 * 1.000 * 2^(-127) 
	//打印为0.000000
	printf("*pFloat的值为: %f\n",*pFloat);

	//9.0放在float类型中
	//9.0转化为二进制浮点数为
	//1001.0
	//转为科学计数法
	//1.001*2^3 
	//(-1)^S * M * 2^E 
	//S = 0 
	//E = 3+127 = 130 二进制为--->10000010
	//M = 00100000000000000000000
	//0 10000010 00100000000000000000000  IEE的存储E规则
	//01000001 00010000 00000000 00000000 在内存中的存储
	*pFloat = 9.0; 

    //01000001 00010000 00000000 00000000 
	//以%d打印是一个非常大的正数
	printf("n 的值为: %d\n",n);

	//以%f打印将
	//01000001 00010000 00000000 00000000用IEEE的转化规则转为
	//0 10000010 00100000000000000000000
	//S = 0 
	//E = 10000010 --->130-127 = 3
	//M = 00100000000000000000000
	//(-1)^S * M * 2^E
	//(-1)^0 * 1.001 * 2^3 = 9.0
	printf("*pFloat的值为: %f\n",*pFloat);

	return 0;
}

运行结果

五、总结:

本章详细讲解了整型家族和浮点型家族数据类型在内存中的存储方式,制作不易,希望对各位有帮助。

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


本文题目:C语言---数据的存储-创新互联
标题来源:http://6mz.cn/article/hjedg.html

其他资讯