c语言 数据的存储


一、数据类型

前面介绍了基本的内置类型,如:
char //字符数据类型
short //短整型
int //整型
long //长整型
float //单精度浮点数
double //双精度浮点数
类型的意义:
1.使用这个类型开辟内存空间的大小(大小决定了使用范围)。
2. 如何看待内存空间的视角

类型的基本分类

整型家族:

1.char
unsigned char
signed char
2.short
unsigned short [int]
signed short [int]
3.int
unsigned int
signed int
4.long
unsigned long [int]
signed long [int]

浮点数家族:

1.float
2.double

构造类型

1.数组类型
2.结构体类型:struct
3.枚举类型:enum
4.联合类型:union

指针类型

例如:
int *pi;

char *pc;

flaot* pf;

void *pv;

空类型

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

二、整型在内存中的存储

1.原码、反码、补码

原码:直接将数值按照正负数的形式翻译成二进制就可以得到原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码;
例如:

int main()
{
	int a = 20;
	//00000000000000000000000000010100 - a的原码
	//0x00000014  -16进制
	//整数的原、反、补码相同

	int b = -10;
	//10000000000000000000000000001010 - b的原码
	//11111111111111111111111111110101 - b的反码
	//11111111111111111111111111110110 - b的补码
	//0xffffff6
	return 0;
}

对于整型来说:数据存放内存中其实存放的是补码
a在内存中的存储:
在这里插入图片描述
b在内存中的存储:
在这里插入图片描述
上面的a和b的存储方式都是倒着存储的,这就是小段(存储)模式。

2.大小端存储

大段存储(大段字节序存储):
把一个数据的低位字节的内容存放在高地址处,高位字节的内容存放在低地址处。

小端存储(小段字节序存储):
把一个数据的低位字节的内容存放在低地址处,高位字节的内容存放在高地址处。
例如:
在这里插入图片描述

相关练习

写一个代码判断当前机器的字节序

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("大段");
	return 0;
}

三、相关例题

1.

int main()
{
	char a = -1;
	//10000000000000000000000000000001  - -1的原码
	//11111111111111111111111111111110	- -1的反码
	//11111111111111111111111111111111	- -1的补码
	//a是char类型的,所以要截断存放
	//11111111 - a
	//最高位1是符号位,整型提升补1
	//11111111111111111111111111111111 -这是补码,打印出来就是-1
	signed char b = -1;
	//b也同样的
	unsigned char c = -1;
	//c的类型是无符号的char,最高位不是符号位,整型提升要补0
	//00000000000000000000000011111111 - %d打印出来就是255
	printf("a=%d b=%d c=%d", a, b, c);
	//%d 打印有符号的整形
	return 0;
}

2.

int main()
{
	char a = -128;
	//10000000000000000000000010000000 - -128的原码
	//11111111111111111111111101111111 - -128的反码
	//11111111111111111111111110000000 - -128的补码
	//10000000 - a
	//整型提升- 补1
	//11111111111111111111111110000000 
	//因为是由%u打印,最高位不是符号位,所以这个数被解析位一正数
	//读出来就是4294967168
	printf("%u\n", a);
	//%u 打印无符号的整形
	return 0;
}

3.

int main()
{
	int a = -20;
	//10000000000000000000000000010100 -a的原码
	//11111111111111111111111111101011 -a的反码
	//11111111111111111111111111101100 -a的补码
	unsigned int b = 10;
	//00000000000000000000000000001010 -b的原码(补码一样的)
	//补码进行运算
	//11111111111111111111111111110110 -补码
	//10000000000000000000000000001001 
	//10000000000000000000000000001010 -原码 也就是-10
	printf("%d\n", a + b);
	return 0;
}

4.

char的取值范围:-128~127
unsigned char 的取值范围:0~255
在这里插入图片描述

int main()
{
	char a[1000];
	//由符号的char的取值范围是:-128~127
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	//i=0时a[0]被赋值为-1
	//i=1时a[1]被赋值为-2
	//...
	//a[127]被赋值为-128,-128再减1就会变为127
	//127再一直减到0
	//strlen的结束标志就时'\0'
	//所以数一数0之前有多少个数字就得到结果了。128+127(255)
	printf("%d", strlen(a));
	return 0;
}

四、浮点型在内存的存储

浮点数家族有:float、double、long double

浮点数的存储规则

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
1.(-1)^S * M * 2^E

2.(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。

3. M表示有效数字,大于等于1,小于2。

4. 2^E表示指数位

IEEE 754规定:
对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

IEEE 754对有效数字M和指数E,还有一些特别规定。
M的规定:M只需要保留小数点后面的数字,剩下不够的位数补0。
E的规定:E是一个无符号整数,如果E为8位,它的取值范围为0~255,E如果是11位,它的取值范围为0到2047。但是科学计数法中的E可以是负数,因此我们需要加上一个中间数。对于8位的E,加上127,对于11的E,加上1023.

举个例子:
十进制的6.0,写出二进制是110.0,按照V的格式写可以得出S=0,M=1.10,E=2,
用32位二进制表示就是:0 10000001 10000000000000000000000

相关例题

int main()
{
	int n = 9;
	float* pFloat = (float*)&n;

	printf("n的值为:%d\n", n);//9

	printf("*pFloat的值为:%f\n", *pFloat);
	//00000000000000000000000000001001 -9的补码
	//0 00000000 00000000000000000001001 把9的补码当成浮点数拿出来解析,
	// (-1)^0*0.00000000000000000001001*2^-126 用V的格式表示
	//0.000000	读出来就是0.000000

	*pFloat = 9.0;
	//1001.0 9.0的二进制
	//1.001*2^3 所以S=0,M=001,E=3
	//0 10000010 00100000000000000000000 -9.0的补码
	printf("num的值为:%d\n", n);//9.0的补码用%d打印就是1091567616
	printf("*pFloat的值为:%f\n", *pFloat);//9.0
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值