目录
一、数据类型基本归类
1、整型家族
2、浮点数家族
3、构造类型(自定义类型)
4、指针类型
5、空类型
二、整型在内存中的存储:原码、反码、补码
三、大小端字节序介绍及判断
四、浮点型在内存中的存储
1、二进制浮点数表示形式
2、有效数字M和指数E的特别规定
(1)有效数字M
(2)指数E
五、练习
一、数据类型基本归类 之前我们已经学习了基本的内置类型:
char//字符型1、整型家族
short//短整型
int//整型
long//长整型
long long//更长的整型
float//单精度浮点数
double//双精度浮点数
char2、浮点数家族
unsigned char
signed char
short
unsigned short
signed short
int
unsigned int
signed int
【C语言进阶|C语言进阶——数据在内存中的存储】long
unsigned long
signed long
float3、构造类型(自定义类型)
double
数组类型4、指针类型
结构体类型 struct
枚举类型 enum
联合类型 union
int* pi;5、空类型
char* pc;
float* pf;
void* pv;
void表示空类型(无类型),通常用于函数的返回类型、函数的参数、指针类型。二、整型在内存中的存储:原码、反码、补码 计算机中的有符号数有三种表示方法:原码、反码、补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位三种表示方法各不相同。
●原码:直接将二进制按照正负数的形式翻译成二进制就可以。三、大小端字节序介绍及判断
●反码:将原码的符号位不变,其他位依次按位取反就可以得到了。
●补码:反码+1
●正数的原、反、补码都相同。
●对于整数来说,数据存放内存中其实存放的是补码。
●大端模式:例:请设计一个小程序来判断当前机器的字节序。
指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中。
●小端模式:
指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。
int main()
{
int a=1;
char* p=(char*)&a;
if(*p==1)
printf("小端!\n");
else
printf("大端!\n");
return 0;
}
四、浮点型在内存中的存储 1、二进制浮点数表示形式
IEEE 754规定任意一个二进制浮点数可以表示成下面的形式:例:
●(-1)^S*M*2^E
●(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数
●M表示有效数字,大于等于1,小于2
●2^E表示指数位
●对于32位浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
十进制的5.0,二进制为101.0,相当于1.01*2^2。则s=0,M=1.01,E=2。
十进制的-5.0,二进制为-101.0,相当于-1.01*2^2。则s=1,M=1.01,E=2。
2、有效数字M和指数E的特别规定 (1)有效数字M
M写成1.xxxxxxx的形式。如:保存1.01时,只保存01,等待读取时,再把第一位的1加上去。这样可以节省1位有效数字。
在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxxx部分。
(2)指数E
E为一个无符号整数(unsigned int)。如:2^10的E是10,所以保存成32位浮点数,必须保存成10+127,即10001001。
如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。
因此,IEEE 754规定,存入内存时E的真实值必须再加上一个中间数。
如果E为8位,中间数为127;如果E为11位,中间数为1023。
E从内存中取出来还可以再分成三种情况:例:
●E不全为0或不全为1
指数E的计算值减去127(或1023)得到真实值,再将有效数字M前加上第一位的1。
如:0.5的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,即1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位,则其二进制表示形式为:
0 01111110 00000000000000000000000
●E全为0
E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
●E全为1
如果有效数字M全为0,表示±无穷大(正负取决于符号位s)
int main()
{
int n=9;
float* pFloat=(float*)&n;
printf("n的值为:%d\n",n);
//9
printf("*pFloat的值为:%f\n",*pFloat);
//0.000000
//n此时为整型,在内存中为00000000000000000000000000001001
//被作为浮点数时,0 00000000 00000000000000000001001,即+0.00000000000000000001001*2^(-126)*pFloat=9.0;
printf("num的值为:%d\n",n);
//1091567616
printf("*pFloat的值为:%f\n",*pFloat);
//9.000000
//n此时为浮点数,在内存中为0 00000000 00000000000000000001001
//被作为整型时,00000000000000000000000000001001
return 0;
}
五、练习 例1:输出什么?
#include
int main()
{
char a=-1;
//11111111,认为第一位为符号位
signed char b=-1;
//11111111,认为第一位为符号位
unsigned char c=-1;
//11111111,unsigned不认为第一位为符号位,认为补码就是原码
printf("a=%d,b=%d,c=%d",a,b,c);
//输出a=-1,b=-1,c=255
return 0;
}
例2:输出什么?
//1
#include
int main()
{
char a=-128;
printf("%u\n",a);
//输出4294967168,%d才正确
return 0;
}
//2
#include
int main()
{
char a=128;
printf("%u\n",a);
//也输出4294967168,%d才正确
return 0;
}
例3:输出什么?
int main()
{
int i=-20;
unsigned int j=10;
printf("%d\n",i+j);
//输出-10
return 0;
}
例4:输出什么?
int main()
{
unsigned int i;
for(i=9;
i>=0;
i--)//无符号类型恒大于等于0,因此恒成立
{
printf("%u\n",i);
//死循环
}
return 0;
}
例5:输出什么?
int main()
{
char a[1000];
int i;
for(i=0;
i<1000;
i++)
{
a[i]=-1-i;
}
//-1 -2 -3 ... -127 -128 127 126 ... 3 2 1 0 -1 -2 ... -127 -128 127...
printf("%d",strlen(a));
return 0;
}
例6:输出什么?
unsigned char i=0;
int main()
{
for(i=0;
i<=255;
i++)//死循环,因为i一直小于等于255
{
printf("hellp world\n");
}
return 0;
}
推荐阅读
- C语言|VC++6.0安装包(免费安装包)(中文)
- [C语言] 最小公倍数
- 刨析《C语言》进阶付费知识完结
- C语言与C++编程|看完这篇你还能不懂C语言/C++内存管理()
- c语言4
- c语言|C语言知识大杂烩(上)(1-10)
- c语言|动态+静态+文件操作 C语言实现通讯录
- 重新学习C语言day14-指针进阶
- [C语言] 三子棋