快速微信网站建设,重慶网站开发,深圳住房建设部网站,自己做的网站怎么让别人访问目录
1.数据类型的详细介绍
2.整型在内存中的存储#xff1a;原码、反码、补码
3.大小端字节序介绍及判断
4.浮点型的内存中的存储解析 1.数据类型的详细介绍
下述是内置类型#xff1a;
char // 字符数据类型
short // 短整型
int // 整型
long …目录
1.数据类型的详细介绍
2.整型在内存中的存储原码、反码、补码
3.大小端字节序介绍及判断
4.浮点型的内存中的存储解析 1.数据类型的详细介绍
下述是内置类型
char // 字符数据类型
short // 短整型
int // 整型
long // 长整型
long long // 更长的整型
float // 单精度浮点型
double //双精度浮点型 在这里就不说不同数据类型在内存中所占数据类型大小了。注意的是C语言中的没有字符串的数据类型
数据类型的意义
1.使用数据类型开辟内存空间的大小
2.如何看待内存空间的视角。
整形家族
char
unsigned char //字符在存储的时候存储的是ASCLL码值AASCLL是整数
signed char //所以在归类的时候字符属于整型家族short
unsigned short [int]
signed short [int]int
unsigned int
signed intlong
unsigned long [int]
signed long [int] //[]中的数据类型是可以省略的 注意 char是signed char还是unsigned char 是取决于编译器的。常见的编译器上char的类型就是signed char。 数据元素个数和数组的名字发生变化数组的类型也会发生变化。 浮点数家族
float
double 构造类型 数组类型结构体类型 struct枚举类型 enum联合类型 union 指针类型
int *pi;
char *pc;
float* pf;
void* pv; void 表示空类型以为就是没有什么类型可以用于函数的返回类型、函数的参数、指针类型。
2.整型在内存中的存储原码、反码、补码 正整型的原反补码都是相同的但负整型数据的反码要符号位不变其他位置取反加上1就会变成补码如下 补码也可以先取反再1得到原码。负整型补码转变成原码有两种方式。
-1//32位机器
原码 10000000 00000000 00000000 00000001
反码 11111111 11111111 11111111 11111110
补码 11111111 11111111 11111111 11111111补码转原码
//方式1
补码 11111111 11111111 11111111 11111111
反码 11111111 11111111 11111111 11111110 -1
原码 10000000 00000000 00000000 00000001 取反//方式2
补码 11111111 11111111 11111111 11111111
中间 10000000 00000000 00000000 00000000 取反
原码 10000000 00000000 00000000 00000001 1 整形数据在内存中是以二进制补码的形式来存放的。本例子列举的是32位机器中的存储。
int a 20;// 20
// 00000000 00000000 00000000 00010100--原码
// 00000000 00000000 00000000 00010100--反码
// 00000000 00000000 00000000 00010100--补码
// 0x00 00 00 14 转换成16进制 在看看存储int b -10;
// -10
// 10000000 00000000 00000000 00001010--原码
// 11111111 11111111 11111111 11110101--反码
// 11111111 11111111 11111111 11110110--补码
// 0xff ff ff f6 转换成16进制
int a 20在VS2017下的存储方式 int b -10在VS2017下的存储方式 例题下属例题都是判断输出什么的
1.
#include stdio.h
int main()
{char a -1;//10000000 00000000 00000000 00000001 原码//11111111 11111111 11111111 11111110 反码//11111111 11111111 11111111 11111111 补码//11111111 截断将一个整型数值赋予一个字符变量的时候要截断//11111111 11111111 11111111 11111111 补码// 因为要输出的是整型应该整型提升有符号位置应该按照符号位来提升 1 补1 0补0//10000000 00000000 00000000 00000000 取反//10000000 00000000 00000000 00000001 原码signed char b -1;//和上面相同//10000001 unsigned char c -1;//10000000 00000000 00000000 00000001 原码//11111111 11111111 11111111 11111110 反码//11111111 11111111 11111111 11111111 补码//11111111 截断//00000000 00000000 00000000 11111111 //整型提升 无符号为整型提升 补0//存储方式是一样的但输出的方式是不一样的 printf(a%d,b%d,c%d, a, b, c); // -1 ,-1,255return 0;
}
2.
#include stdio.h
int main()
{char a -128;
//10000000 00000000 00000000 10000000 原码
//11111111 11111111 11111111 01111111 反码
//11111111 11111111 11111111 10000000 补码
//截取 10000000
//整型提升 看char是有符号的char 整型提升是看原来的数据类型来提升的
//11111111 11111111 11111111 10000000 //输出的是无符号数可以直接输出无符号数只有正的printf(%u\n, a);// 4294967168return 0;
}
3.
int main()
{char a 128;// 00000000 00000000 00000000 10000000// 10000000 截断// 11111111 11111111 11111111 10000000 整型提升printf(%u\n, a);return 0;
}
4.
int main()
{int i -20;//10000000 00000000 00000000 00010100 原码//11111111 11111111 11111111 11101011 反码//11111111 11111111 11111111 11101100 补码unsigned int j 10;//00000000 00000000 00000000 00001010 原码 补码//11111111 11111111 11111111 11110110//10000000 00000000 00000000 00001001//10000000 00000000 00000000 00001010 //-10printf(%d\n, i j);//-10 //输出的形式有符号数 相加之后本来是无符号数的return 0;
}
5.
#include stdio.h
#include windows.h
int main()
{unsigned int i;for (i 9; i 0; i--) //会无限制的循环i不可能是负数的因此会一直大于0{printf(%u\n, i);Sleep(100);} return 0;
} //可以执行一下 从零之后就是一个更大的数字了6
#include stdio.h
int main()
{char a[1000];int i;for (i 0; i 1000; i){a[i] -1 - i; }//-1 -2 .......-128 127 126 3 2 1 0 128127255printf(%d, strlen(a)); //找到\0 其ASCLL码值为 0 找到0 return 0;
}
7.
#include stdio.h
unsigned char i 0;
int main()
{for (i 0; i 255; i){printf(hello world\n);//死循环}return 0;
}
循环限制条件是无符号数是一定要注意设置的限制条件一定要大于0。
3.大小端字节序介绍及判断 大端存储模式是指数据的低位保存在内存的高地址中而数据的高位保存在内存的低地址中 小端存储模式是指数据的低位保存在内存的低地址中而数据的高位,保存在内存的高地址中。 为什么会存在大端存储和小端存储呢 其思想源于格列夫游记两个国家由于鸡蛋应该是先从大头剥还是从小头处开始剥皮的问题开始了战争。 小端存储举一个例子,下面是一个数
int a 0x11223344; 下面就是数据在VS2017的存储方式。 数据的低位应该是这样理解的123 3就是这个数据的低位。看数据的低位放在了低地址上数据的高位放在了高地址上。
做个表格详细了解一下
地址0x007EFBFC0x007EFBFD0x007EFBFE0x007EFBFE小端存储44332211大端存储11223344低地址高地址 我们再写一个小程序来判断一个编辑器是大端存储还是小端存储。
#include stdio.h
int main()
{int a 1;//存储方式是 0x00 00 00 01 如果只取一个字节就比较好判断了char *pa (char *)a;//()括号中的强制类型转化if (*pa 1){printf(小端存储\n);}else{printf(大端存储\n);}return 0;
} 还可以将这个逻辑封装到一个函数中大家可以练习一下在以后的时候中好的函数是经常调用的。
封装函数
void check_byte()
{int a 1;if ((char *)a)printf(小端存储\n);elseprintf(大端存储\n);
} 4.浮点型的内存中的存储解析 大家想一下 3.14159 1E10.在内存中是如何存储的当然和整型是不一样的。先看下面的例子。
int main()
{
int n 9;
//00000000 00000000 00000000 00001001
float *pFloat (float *)n;
printf(n的值为%d\n,n);
printf(*pFloat的值为%f\n,*pFloat);
//以浮点数的存储方式取出是不正常值两者存储的方式是不一样的*pFloat 9.0;
printf(num的值为%d\n,n);
printf(*pFloat的值为%f\n,*pFloat);
return 0;
} 以下是上述代码的值可以往后看看浮点型是如何存储的就理解了在文章的最后会有解析的。 浮点数的存储规则 根据国际标准IEEE电气和电子工程协会 754任意一个二进制浮点数V可以表示成下面的形式 . (-1)^S * M * 2^E . (-1)^s表示符号位当s0V为正数当s1V为负数。 . M表示有效数字大于等于1小于2。 . 2^E表示指数位 举个例子就明白了,
将十进制的 5.0 1 转换成二级制101.1相当都1.01×2^2
按上述的格式就是 S0表示正数M1.01E2。如果是-5的话那就是S-1了。 再来一个 5.5 101.1二进制 转换成科学计数法 1.011*2^2 (-1)^0*1.011*2^2
S0, M1.011, E2。 0.5 大家思考一下 注意一下浮点数中没有原反补的概念 单精度浮点数存储模型4byte 双精度浮点型8byte
特殊规定 1. M值的存储方式 前面说过 1≤M2 也就是说M可以写成 1.xxxxxx 的形式其中xxxxxx表示小数部分。IEEE 754规定在计算机内部保存M时默认这个数的第一位总是1因此可以被舍去只保存后面的xxxxxx部分。 此种方式可以提升精度 比如保存1.01的时候只保存01等到读取的时候再把第一位的1加上去。这样做的目的是节省1位有效数字。以32位浮点数为例留给M只有23位将第一位的1舍去以后等于可以保存24位有效数字。 2. E的存储方式 E为一个无符号整数是无法判读E是正负的。如果E为8位它的取值范围为0~255如果E为11位它的取值范围为0~2047。但是科学计数法中的E是可以出现负数的所以IEEE 754规定存入内存时E的真实值必须再加上一个中间数对于8位的E这个中间数是127对于11位的E这个中间数是1023。比如2^10的E是10所以保存成32位浮点数时必须保存成10127137即10001001。 指数E从内存中中取出还可以再分为三种情况 1.E不全为0或者不全为1
这时浮点数就采用下面的规则表示即指数E的计算值减去127或1023得到真实值再有效数字M前加上第一位的1。 比如 0.51/2的二进制形式为0.1由于规定正数部分必须为1即将小数点右移1位则为1.0*2^(-1)其阶码为-1127126表示为01111110而尾数1.0去掉整数部分为0补齐0到23位00000000000000000000000则其二进制表示形式为:
0 01111110 00000000000000000000000 2.E全为0 这时浮点数的指数E等于1-127或者1-1023即为真实值 有效数字M不再加上第一位的1而是还原为0.xxxxxx的小数。这样做是为了表示±0以及接近于0的很小的数字。 3.E全为1 这时如果有效数字M全为0表示±无穷大正负取决于符号位s.
实际的例子
5.5
float f 5.5f;// 转换成SME的形式 -1^0 * 1.011 * 2^2//S 0;M 1.011; E 2; 2127129//0 10000001 01100000000000000000000//0100 0000 1011 0000 0000 0000 0000 0000// 4 0 b 0 0 0 0 0
4.小节开始的例题
#include stdio.h
int main()
{int n 9;float *pFloat (float *)n;//00000000 00000000 00000000 00001001//0 00000000 0000000 00000000 00001001//(-1)^0 * 0.00000000000000000001001 * 2^-126 相当于0了printf(n的值为%d\n, n);printf(*pFloat的值为%f\n, *pFloat);*pFloat 9.0;//9.0的存储方式//1001二级制 1.001^3 3127130//0 1000 0010 00100000000000000000000//01000001000100000000000000000000 存储方式printf(num的值为%d\n, n);printf(*pFloat的值为%f\n, *pFloat);//1,091,567,616return 0;
} 由于存储方式的不同和访问方式的不同会造成数据错误。