数据的存储

1.数据类型

基本的内置类型
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数 - 4个字节
double //双精度浮点数 - 8个字节

有无符号

     char a;
	//有无符号取决于编译器,大部分编译器下的char是有符号的(signed char)

	//short int long 都是有符号的
	//short == signed short
	//int == signde int
	//long == signed long

所以unsignedsigned如何理解?拿char举例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
自定义类型
数组类型
数组是有类型的,是我们自定义的类型
在这里插入图片描述

构造类型

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

指针类型

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

空类型

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

整型在内存中的存储

正整数:原码,反码,补码相同;
对于整形来说:数据存放在内存中其实存放的是补码,使用补码,可以将符号位和数值统一处理
在这里插入图片描述

大小端存储

在这里插入图片描述

小端字节序(以字节为单位讨论顺序)存储:把一个数字的低位字节的内容,存放在内存的低地址处,把高位字节的内容存放在内存的高地址处

大端字节序存储:把一个数字的低位字节的内容,存放在内存的高地址处,把高位字节的内容存放在内存的低地址处

如何判断当前机器是大端还是小端存储?

在这里插入图片描述

int main()
{
	int a = 1;
	char* p = (char*)&a;//a的地址的类型是int* 想要赋给char*要强制类型转换
	//p解引用,访问一个字节
	if (*p == 1)
		printf("小端存储\n");
	else
		printf("大端存储\n");
	return 0;
}

例题

1.下面这段代码打印什么?

    char a = -1;
	unsigned char b = -1;
	printf("a=%d b=%d ", a, b);

会打印a=-1;

  1. -1是int类型的整形的原码是10000000000000000000000000000001;反码是11111111111111111111111111111110;存放在内存中的补码是11111111111111111111111111111111;
  2. -1赋给a,a的类型是char,-1的类型是int,所以会发生截断,只会把一个字节赋给a;
    a的补码就是11111111;
  3. printf("%d",a);%d - 以有符号整数(整形)的形式进行打印,而a的类型是char,会发生整形提升,按照符号位补充,高位补1。整形提升后a的补码是11111111111111111111111111111111;
  4. 打印a就是打印a的原码也就是1000000000000000000000001;也就是-1

会打印b=225;

  1. -1把补码赋给b也会发生截断,b又是无符号数,所以原码,反码,补码相等,都为11111111;无符号数整形提升的时候高位补0,所以整型提升后b的补码是0000000000000000000000011111111,printf("%d",b);,打印的时候看最高位是0,把b看作整数打印

2.运行下面的代码会打印什么?

int main()
{
	char a = -128;
	printf("%u", a);
	return 0;
}
  1. -128是个整形,在内存中原码10000000000010000000;反码1111111111111101111111;补码是1111111111111110000000;
  2. -123赋给char类型的a,发生截断,a的补码就是10000000
  3. %u,以无符号数的形式,打印整形,打印整形就要整形提升,char a;a是有符号数,高位的1就是符号位,整型提升后a的补码就是11111111111111111110000000;
  4. 打印是以无符号数的形式,所以11111111111111111110000000直接就是原码

在这里插入图片描述
3.下面的打印什么?

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

与上题一样,128的原,反,补码相同,赋给char类型的a发生截断,a的补码就是10000000,printf("%u\n",a),以无符号的形式打印整形,a就先整形提升,因为a是有符号数,高位补1,这时a的补码是111111111111111110000000,因为以无符号的形式打印,把a的补码就看作原码打印了;

**4.**运行下面的代码会打印什么?

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

-20的
原码10000000000000000000000000010100,
反码111111111111111111111111111111101011,
补码111111111111111111111111111111101100,
10的原反补码相同
都是00000000000000000000000000001010
-20+10也就是-20的补码和10的补码相加,得到的补码是
11111111111111111111111111111111110110
printf("%d",a);%d - 以有符号整数(整形)的形式进行打印,
所以要打印-20+10原码,得到1000000000000000000000000001010,也就是-10
在这里插入图片描述

**5.**运行下面的代码会打印什么?会死循环

int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)//由于i是无符号整形,>=0恒成立
	{
		printf("%u\n", i);
		
	}
	return 0;
}

在这里插入图片描述
**6.**运行下面的代码会打印什么?

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

在这里插入图片描述
在这里插入图片描述
**7.**运行下面的代码会打印什么?死循环

unsigned char i = 0;
//unsigned char的取值范围是0~255;

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

浮点型在内存中的存储

常见的浮点数
3.14159
1E10(科学计数法:表示1.0*(10的10次方))

	int n = 9;
	float* p = (float*)&n;
	printf("n的值为,%d\n", n);
	printf("*p的值为,%f\n", *p);
	*p = 9.0;
	printf("n的值为,%d\n", n);
	printf("*p的值为,%f\n", *p);

在这里插入图片描述
在这里插入图片描述

通过运行上面的代码,可以发现浮点数和整形的存储是不一样的
任意一个二进制浮点数V都可以表示成下面的形式
在这里插入图片描述
所以对于能用二进制表示的浮点数,就可以只记录S,M,E就可以把浮点数表示出来
在这里插入图片描述
在这里插入图片描述

详情看课件
验证float类型在内存中如何存储:
在这里插入图片描述

在这里插入图片描述
那么float类型如何取出?

当E不全为0或不全为1

浮点数就采用下面的规则表示,即指数E的计算值减去127(float)或1023(double),得到真实值,再将有效数字M前加上第一位的1。

当E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,
有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。

当E全为1

这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)

作业

程序的执行结果为

int main()
{
	//200在内存中000000000000000000000000 1100 1000
	//100在内存中000000000000000000000000 0110 0100

	//截断后a - 11001000   b - 01100100
	unsigned char a = 200;
	unsigned char b = 100;
	unsigned char c = 0;
	c = a + b;
	//操作符两端达不到整形大小,会发生整型提升
	//a+b 000000000000000000000001 00101100
	//赋值给c会发生截断 c - 00101100
	printf("%d %d",a + b, c);//300 44
	//以有符号整形的方式打印,c首页会整型提升,因为是c是无符号类型,高位补0
	//a+b在内存中是000000000000000000000001 00101100,把它看作补码,又因为高位是0,所以原反补相等
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值