基本数据类型
整形:int char short long
浮点型:double float
结构型:struct enum union
指针类型:int* char* float* void*
整型的存储
整型以二进制的原码,反码,补码来表示,在内存中以补码的形式存储
正整数:原反补码形式均相同(直接将整数转化为二进制)
负整数:原码最高位取1表示负数,其余不变;反码最高位不变,其余取反;补码为反码+1
大端存储和小端存储
大端模式:将数据的低位保存在高地址中,数据的高位保存在低地址中
小端模式:将数据的低位保存在低地址中,数据的高位保存在高地址中
因为寄存器的宽度大于一个字节,而最小的char类型都要占用8bit也就是一个字节,所以必定会产生一个多个字节安放顺序的问题
整型的存储与输出问题
char a=-1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
a=-1,b=-1,c=255
-1的原反补为
10000000000000000000000000000001
11111111111111111111111111111110
11111111111111111111111111111111
当char类型以int 型输出时,截断,整型提升
11111111---->补符号位---->1111111111111111111111111(-1的补码)
所以输出-1,signed char同理。
而unsigned char是无符号数,在整型提升时直接高位补0,00000000000000000000000011111111(255的补码),所以输出255
char a=-128;
printf("%u",a);
a=4294967168
-128=10000000000000000000000010000000
11111111111111111111111101111111
11111111111111111111111110000000
char a中只能存放10000000,之后整型提升,char a是有符号数,补符号位,
11111111111111111111111110000000(4294967168的补码,对于无符号数来说也是原码)
char a=128;
printf("%u",a);
a=4294967168
128=
00000000000000000000000010000000
00000000000000000000000010000000
00000000000000000000000010000000
截断,整型提升
11111111111111111111111110000000(4294967168的补码,对于无符号数来说也是原码)
int -20;
unsigned int j=20;
printf("%d",i+j);
-10
只要数据类型放得下,则不影响存储数据的值,即不发生截断
unsigned int i;
for(i=9;i>=0;i--)
{
printf("%u",i);
}
9
8
7
6
5
4
3
2
1
0
4294967295
4294967294
4294967293
4294967292
4294967291
4294967290
无限循环
当i==0时,0此时再减1=-1,-1补码为11111111111111111111111111111111,无符号数为4294967295(无符号数永远大于0,所以死循环)
无限循环可以加Sleep()函数使得循环速度变慢,头文件#include<windows.h>
char a[1000];
int i;
for(i=0;i<1000;i++)
{
a[i]=-1-i;
}
printf("%d",strlen(a));
a[0]=-1 a[1]=-2 ...因为a[1000]是字符数组,所以a[i]的取值只能是-128~127,当a[i]变成-128时,再减1,就变成了127,即-1 -2 -3 ......-127 -128 127 126 ......3 2 1 0
strlen()函数统计的是\0之前的字符个数,所以有128+127=255个
注:无符号字符数组unsigned char 的取值范围为0~255
浮点型的存储
double、float、long double
根据国际标准IEEE电气电子工程师学会745,任意一个二进制浮点数V可以表示成下面的形式
(-1)^S * M * 2^E,其中S为符号位,S=0为正数,S=1为负数;M表示有效数字,1.xxxxxxx<2;
2^E为指数位。也就是说只要存储S、M、E三个量就可以确定一个浮点型数据。例如:V=5.1
化为二进制为101.1--->1.011*2^2 S=0;M=1.011;E=2。
对于32位的浮点数,最高1位是符号位,接着是8位指数E,接着是23位有效数字M
对于64位的浮点数,最高1位是符号位,接着是11位指数E,接着是52位有效数字M
IEEE对于M、E有些特殊的规定:
M总是1.xxxxxxx,所以开头的1省去,只保存xxxxx,例如1.01,只保存01,这样就有24位可以保存M
E的取值范围要么是255要么是2047,但是数学上E是可以取负数的,所以在存储E时要加上一个中间数:127/1023
若E全为0,则E的真实值总为1-127/1-1023,这是为了表示接近于0的数字
若E全为1,这时,如果有效数字M全为0,则表示±∞。