C语言在内存中的存储

 

一、类型的基本归类

 整形家族

1.char :unsigend char 、signed char

2.short unsigend short[int]、signed short[int]

3.int unsigned int、signed int

4.long unsigned long[int]、signed long[int]

浮点型家族

float、double

构造类型

组类型、结构体类型、枚举类型、联合类型

指针类型

int*、char*、float*、void*

空类型:函数的返回参数、函数的参数、指针类型

二、整形在内存中的存储:

2.1原码、反码、补码

 三种表示方法有符号位和数值位,符号位0表示正数,1表示负数

原码:直接翻译

反码:符号位不变、其他位按位取反

补码:反码+1

结论:1.数据存放内存其实存放的是补码 2.正数的原码。反码、补码相同

实例:

#include<stdio.h>
int main()
{
    int a = 20;
	00000000000000000000000000010100 -a的原码、反码、补码
	int b = -10;
	10000000000000000000000000001010 -b的原码
	11111111111111111111111111110101 -b的反码
	1111 1111 1111 1111 1111 1111 1111 0110 -b的补码
	ff ff ff f6
	00000000000000000000000000010100
	11111111111111111111111111110110
	00000000000000000000000000001010 ->10
	int c = a + b;
	printf("%d\n", c);
	return 0;
}
 

2.2大小端的介绍

大端(存储)模式:数据的低位保存在内存的高地址处。数据的高位保存在内存的低地址处。

小端(存储)模式:数据的低位保存在内存的低地址处。数据的高位保存在内存的高地址处。

实例:判断当前编译器使用的是大端存储还是小端存储

  #include<stdio.h>
  int check_sys()
  {
	int p = 1;
	return *(char*)&p;
  }
  int main()
    {
	if (check_sys() == 1)//ASCII码值的比较
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

实例练习:

实例一:

#include <stdio.h>
int main()
{
	char a = -1;
	//10000000000000000000000000000001
	//11111111111111111111111111111110
	//11111111111111111111111111111111
	//11111111 截断
	//11111111111111111111111111111111
	//11111111111111111111111111111110
	//10000000000000000000000000000001 -> -1
	signed char b = -1;
	//同上-1
	unsigned char c = -1;
	//11111111
	//0000000000000000000000011111111 ->255
	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}

实例二:

实例2:
#include <stdio.h>
//%u - 打印的是无符号整数,认为内存中对应的是一个无符号数
//%d - 打印的是有符号整数,认为内存中对应的是一个有符号数
int main()
{
	char a = -128;
	//10000000000000000000000010000000
	//11111111111111111111111101111111
	//11111111111111111111111110000000
	//10000000
	//00000000000000000000000010000000 ->128//err,
	// 提升按照的是它的类型,而打印看的是它在内存中的存储,打印不影响它原来本身的提升
	//11111111111111111111111110000000 ->4294967168 ok
	printf("%u\n", a);
	return 0;
}

实例三:

#include <stdio.h>
int main()
{
	char a = 128;
	//00000000000000000000000010000000
	//10000000
	//11111111111111111111111110000000 ->4294967168 ok
	printf("%u\n", a);
	return 0;
}

实例四:

#include<stdio.h>
int main()
{
	int i = -20;
	//10000000000000000000000000010100
	//11111111111111111111111111101011
	//11111111111111111111111111101100
	unsigned int j = 10;
	//00000000000000000000000000001010
	//11111111111111111111111111101100
	//11111111111111111111111111110110 i+j的补码
	//11111111111111111111111111110101 i+j的反码
	//10000000000000000000000000001010 i+j的原码 -> -10
	printf("%d\n", i + j);
	return 0;
}

补充:
char类型的取值范围:-128~127(图像法记忆)
unsigned char的取值范围是:0~255
short类型的取值范围:-32768~32767
unsigned short的取值范围:0~65535

实例五:

#include<stdio.h>
int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)
	{
		printf("%u\n", i);
	}
	//因为unsigned是无符号数,所以一定大于等于0,所以死循环
	return 0;
}

实例六:

#include<stdio.h>
#include<string.h>
int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;//-1 -2 -3 -4 ....-128 127 126..3 2 1 0,strlen遇到0就结束
	}
	printf("%d", strlen(a));//255
	return 0;
}

实例七:

#include <stdio.h>
unsigned char i = 0;
int main()
{
	for (i = 0; i <= 25; i++)//由于unsigned char取值范围是:0~255,所以死循环
	{
		printf("hello world\n");
	}
	return 0;
}

三、浮点型的存储:
IEEE754表示任意一个二进制浮点数V可以表示成下面的形式
(-1)^S*M*2^E
S:正数为0,负数为1(float和double都占用1个bit)
M:1<=M<=2,只保留小数位,个位数不保留,因为个位数都是1(float占用:8个bit,double占用:11个bit)
E:在原有的E的数值上+127(float占用:23bit,double占用:52bit)
  1.不为全0或者全1:真实值
  2.为全0:M的个位数不在补充,E=-126
  3.为全1:表示的是+-无穷大的一个数

实例解析:

#include<stdio.h>
int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);//9
	//0 00000000 00000000000000000001001
	//S=0 E=00000000~-126 M=0.00000000000000000001001
	printf("*pFloat的值为:%f\n", *pFloat);//0.0
	*pFloat = 9.0;
	//9.0=1001.0=1.001*2^2
	//S=0 E=129 M=001
	//0 10000010 00100000000000000000000
	//01000001000100000000000000000000 -> 1091567616
	printf("num的值为:%d\n", n);//1091567616
	printf("*pFloat的值为:%f\n", *pFloat);//9.0
	return 0;
}

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨后有晴天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值