数据类型的介绍
我们所学的数据大致可以分成以下几类
一类是整形数据(char,short,int,long)
一类是浮点型数据(float,double)
一类是构造类型数据(数组类型,结构体类型(struct),枚举类型(enum),联合类型(union))
还有一类是指针类型(int *,char *,float *,double *)
最后一个就是空类型void
二.整形在内存中的存储
计算机中数据的存储有三种形式:
原码(将数据按照正负号的形式直接写成二进制)
反码(正数的原码和反码相同,负数的反码是原码的符号位不变,其余的取反)
补码(正数的原码和补码相同,负数的反码是反码加1)
而在计算机中进行运算的是补码的运算,数据存放在内存中的是补码。
三.大小端存储
我们现在所用的计算机都是小端存储,数据的低位放在低地址,高位放在高地址
正数的存储具体如图所示:
正常情况下a=20;则在16进制的情况下应该是0x00000014,因为是小端存储,所以数据中的低位14应该放在前面就是低地址处。
负数的存储具体如图所示:
负数存储的过程中先写出负数的原码
原码:100000000000000000000000000001010
反码:1111111111111111111111111111111110101
补码:1111111111111111111111111111111110110
补码以16进制的表示形式就是0xfffffff6
又因为是小端存储所以f6在低位。
#include<stdio.h>
int check()
{
int i = 1;
char* p= &i;
return *p;
}
int main()
{
int ret = check();
if (ret== 1)
{
printf("小端方式");
}
else
{
printf("大端方式");
}
}
运行结果如图所示:
四.数据在内存中的存储的实例
下面我们用几个实例来看看数据具体的是如何在内存中存储的
1.输出什么?
#include <stdio.h>
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0; }
char默认的就是有符号的 所以char和signed char相同,char是1个字节
-1的补码是11111111
因为要以整数的形式输出,所以要有符号的整形提升,将1个字节的提升为4个字节
所以前面开始补1, 补码为11111111111111111111111111111111
反码为111111111111111111111111111111110
原码为10000000000000000000000000000001
所以输出的就是-1
而无符号的整形提升(前面全都补0,无论正数还是负数)
补码为00000000000000000000000011111111
所以输出为255
2.
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n",a);
return 0;
}
a的补码是10000000
因为要无符号输出所以要整体提升11111111111111111111111110000000
所以除以的就是这个数4294967168 正好是上面二进制数转换成10进制的数
3.
#include <stdio.h>
int main()
{
char a = 128;
printf("%u\n",a);
return 0;
}
因为char的范围是-128~127,但128超过范围,二进制原码为10000000
原码和补码相同,因为要输出一个无符号的数所以进行整形提升11111111111111111111111110000000
和上面那个输出相同
4.
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
}
i的原码10000000000000000000000000010100
反码11111111111111111111111111101011
补码11111111111111111111111111101100
j的补码00000000000000000000000000001010
i的补码加j的补码为
11111111111111111111111111110110
反码11111111111111111111111111110101
原码10000000000000000000000000001010
所以输出为-10
5.
#include<Windows.h>
int main()
{
unsigned int i;
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
Sleep(1000);
}
}
无符号数的大小永远大于0;所以当输出0之后i就成了-1;
-1的补码是11111111111111111111111111111111
无符号输出所以就是4294967295
6.
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
strlen函数在“\0”的时候停止,也就是转换成二进制为0的时候停止
char的范围是-128~127 所以这就是一个轮回127+1就成了-128
所以要从-1到0就必须先从-1到-128
在从-128到0这一共就是127+128=255次
7.
#include <stdio.h>
unsigned char i = 0;
int main()
{
for(i = 0;i<=255;i++)
{
printf("hello world\n");
}
return 0;
}
无符号char最大是11111111是255所以肯定不越界,所以会一直循环下去
五.浮点数的存储
int main()
{
int n = 9;
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;
}
n=9所以第一问输出9,这没问题;
第二问中:
转换成10进制为1091567616
第四问浮点数正好是9.000000
这就是我所总结的数据在内存中存储的方式,如果有不对的地方,还请大家指正。