整型和浮点型数据在内存中的储存方式
原创
©著作权归作者所有:来自51CTO博客作者rythshys的原创作品,请联系作者获取转载授权,否则将追究法律责任
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//C语言类型分为2类,1.内置类型,2.自定义类型
//自定义类型:自己创造和改变
//unsigned char //0-255
//signed char//-128-127
//short a=10或者 short int a=10
//int 和 long 同理
//float单精度,double双精度
//构造类型 数组类型,结构体类型,枚举类型,结构体类型
//指针类型 空类型(void)返回类型的时候,函数参数,指针类型
void test()//没有接受100
{
printf(" hehe ");
}
//int check_sys()
//{
// int a = 1;
// charp = (char)&a;
// return*p;
//}
int check_sys()
{
int a = 1;//1的补码:01111111
return*(char*)&a;//char:指针类型决定了指针解引用操作符能访问几个字节
//char*p;//*p访问了1个字节;
//指针类型决定了指针+1,-1加或减是几个字节
//不管是大端还是小端,解引用取值都是从左往右取
//地址从左往右--低地址到高地址
//大端--数据高位存低地址
//小端--数据低位存低地址
}
int main()
{
////test(100);
//int a = 20;
//int b = -10;
//计算机中的有符号数(整型)有三种表示方法:原码反码补码 符号位和数值位两部分0正一负
//浮点型不以原码反码补码 形式储存 无符号数=正数:原码反码补码相同
//整型在内存中的储存
//反码:原码符号位不变,其他位按位取反 反码+1=补码
//地址里存的是倒着写的8个16进制,存的也是补码
//补码可以将符号位和数值统一处理,加减也可统一处理(cpu只能算加减)
//小端(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中;
//从左往右 数据:高到底。 地址:低到高
//写一段代码告诉我们当前机器的字节序是什么
//int ret = check_sys();
//if (ret == 1)
//{
// printf("小端\n");
//}
//else
//{
// printf("大端\n");
//}
//int a = 0x11223344;
//
// int*p = &a;
// *p = 0;
//char*p = &a;
//*p = 0;
//int a = 10;//-1的补码是全1 11111111111111111111111111111111
////三种形式都是存11111111,只是拿出来的时候不一样了
//signed char b = -1;//1个字节是8个bit位
//unsigned char c = -1;
////存进去的是11111111
////整形提升00000000000000000000000011111111
////由于是正数,所以原反补码相同
////所以输出255
////已当前数为前提,先存进去。然后再提升,再拿出来
//printf("a=%d,b=%d,c=%d", a, b, c);
//%d就意味着打印的是个整形,所以需要整形提升
//整型提升,按照原符号的符号位来提升
//整形提升有两种:有符号的和无符号的
//最左面的一位数为1则在最高位前补1,如果最高位是0则在前面补0
//无符号的直接补0
//char a = -128;
//原码:10000000000000000000000010000000
//反码:11111111111111111111111101111111
//补码:11111111111111111111111110000000
//char :访问得到10000000与地址大小端联系 从右端(低位访问),以小端储存,,1个字节存到最左端,char*修改时,内存最左边被修改
//11111111111111111111111110000000
//先进行整型提升,提升后变成正数,然后再转无符号数,由于是
//正数,所以才进行原反补码相同的轮次,注意顺序
//printf("%u\n", a);
//%d打印10进制有符号数字
//%u打印10进制无符号数字
//有符号的char是-128--127直接
//-128补码原码相同,所以当出现10000000直接认定为-128
//无符号char的范围是0--255 当结果为256时,放进去再拿出来结果变成1
//有符号数最高位表示正负,无符号数最高位表示大小
//int i = -20;
////补码11111111111111111111111111101100
//unsigned int j = 10;
////补码00000000000000000000000000001010
////加之后补码10000000000000000000000000000110
////结果原码10000000000000000000000000001010=-10
//printf("%d\n", i + j);
//unsigned int i;
//for (i = 9; i > 0; i--)
//{
// printf("%u\n", i);//结果陷入循环,无符号数最小是0
//}
//char a[1000];
//int i = 0;
//for (i = 0; i < 1000; i++)
//{
// a[i] = -1 - i;
//}//-1:11111111 -128:10000000 -127:01111111
////先减1取反,然后在输出
////-126的原码11111110 反码 10000001 补码10000010
////-127的原码11111111 反码 10000000 补码10000001
////按照补码的顺序
////-129的补码01111111 输出的反码 01111111 原码01111111与127相同
//printf("%d", strlen(a));//2进制中/0的asc值为0
//当-1-i的结果原码为0时,则遇到/0停止,总共255个数字
//double d = 1E10;
//printf("%lf\n", d);
//int i初始定义为int代表存进去是4字节,char访问代表出来时是取出1字节
int n = 9;
//存进去是补码:00000000000000000000000000001001
float *pfloat = (float*)&n;//强制类型转化
printf("n的值为%d\n", n);
printf("*pfloat的值为:%f\n", *pfloat);//整形放进去,
//取的时候0 00000000 00000000000000000001001
//(-1)^0*0.00000000000000000001001*2^-126 结果相当于+0 一般小数点后取6位(猜测)
//所以结果为0.000000
*pfloat = 9.0;//2进制1001.0
//1.001*2^3
//(-1)^0*1.001*2^3
//存进去的是: 0 10000010 00100000000000000000000;3+127 001后补
printf("num的值为:%d\n", n);//指针访问可以访问4个字节
//此时访问的时候是按整形访问即:01000001000100000000000000000000
//1091567616
printf("*pfloat值为:%f\n", *pfloat);//9.000000
//9.0
//1001.0
//(-1)^0*1.001*2^3;
//(-1)^S*M *2^E;
//S-0;//0正1负
//M-1.001;
//E-3;
//M总是1<M<2,所以小数点前的1不存,取出的时候再补上
//E是1个无符号数,结果是正负都需要加一个中间数 8位+127 11位+1023
//S(1bit) E(8bit) M(23bit)//32位 (单精度)float
//S(1bit) E(11bit) M(52bit)//64位 (双精度)double
//float f = 5.5;
//5.5转换为2进制为101.1 0.5转换为2进制就是1
//(-1)^0*1.011*2^2
//s=0;
//m=1.011
//E=2 存进去是129;结果为 0 10000001 01100000000000000000000
//内存里面看的时候是16进制 0100 0000 1011 0000 0000 0000 0000 0000
//转换成16进制是40b00000
//取E的时候又分为3种情况(E是1个无符号数)
//1、8个比特位不为全0或全1
//1、8个比特位为全0 E=-127才会这样 这样的数字几乎不存在,了解一下
//1、8个比特位为全1 E=128才会这样 了解一下
return 0;
}