目录
1. 数据类型介绍
1.1 类型的基本归类
整型家族
浮点数家族
构造类型(自定义类型)
指针类型
空类型
2. 整型在内存中的存储
2.1 原码、反码、补码
2.2 大小端(字节序的问题)
2.3 练习
2.3.1 设计程序来判断当前机器的字节序
2.3.2 练习二 - 下面程序输出什么
2.3.3 练习三
2.3.4 练习四
2.3.5 练习五
2.3.6 练习六
2.3.7?练习七
2.3.6 练习六
3. 浮点型在内存中的存储
3.1 浮点型存储例子
3.2 浮点数存储规则
1. 数据类型介绍
常见的基本内置类型:
char? ? ? ? ?//字符数据类型 short?? ??? ?//短整型 int? ? ? ? ? ? //整形 long? ? ? ? ?//长整型 long long ? //更长的整形 float? ? ? ? ? ?//单精度浮点数 double ? ? ?//双精度浮点数
1.1 类型的基本归类
整型家族
char ?? ?unsigned char ?? ?signed char short ?? ?unsigned short[int] ?? ?signed short[int] int ?? ?unsigned int ?? ?signed int long ?? ?unsigned long[int] ?? ?signed long[int]
浮点数家族
float
double
构造类型(自定义类型)
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
指针类型
int* pi
char* pc
float* pf
void* pv
空类型
void表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型。
2. 整型在内存中的存储
计算机中的整数有三种表示方法,即原码、反码、补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”
2.1 原码、反码、补码
原码:直接将二进制按照正负数的形式翻译成二进制就可以。
反码:符号位不变,数值位与原码依次按位取反就可以得到了。
补码:反码+1就得到补码。
正数的原、反、补码都相同。
对于整型来说:数据存放内存中其实存放的是补码。
2.2 大小端(字节序的问题)
大端字节序存储:当一个数据的低字节数据存放在高地址处,高字节序存放在低地址处,这种存储方式就是大端字节序存储。
小端字节序存储:当一个数据的低字节数据存放在低地址处,高字节序存放在高地址处,这种存储方式就是小端字节序存储。
2.3 练习
2.3.1 设计程序来判断当前机器的字节序
具体参见:判断当前机器的字节序(大小端问题)
2.3.2 练习二 - 下面程序输出什么
#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;
}
思路:1.a, b, c在内存中均为 -> 11111111(-1 补码中的后8位)?
? ? ? ? ? ?2.整型提升时按符号位补齐
输出结果为:a = -1, b = -1, c = 255
2.3.3 练习三
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n", a);
return 0;
}
输出结果为:4294967168(11111111 11111111 11111111 10000000转为十进制)?
2.3.4 练习四
#include <stdio.h>
int main()
{
char a = 128;
printf("%u\n",a);
return 0;
}
结果与练习三相同
2.3.5 练习五
int i= -20;
unsigned int j = 10;
printf("%d\n", i+j);
//按照补码的形式进行运算,最后格式化成为有符号整数
按照补码进行运算,按照原码进行%d打印
输出结果为 -10
2.3.6 练习六
#include <stdio.h>
#include <windows.h>
int main()
{
unsigned int i;
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
Sleep(1000);
}
return 0;
}
由于无符号整型中没有负数,因此运行结果为死循环:
9 8 7 6 5 4 3 2 1 0 4294967295?4294967294?4294967293…
2.3.7?练习七
#include <stdio.h>
int main()
{
char a[1000];
int i;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a));
return 0;
}
输出结果为:255(-1? -2? -3 … -127 -128 127 126 125 … 5 4 3 2 1 0)
无符号char的取值范围:0~255
有符号char的取值范围:-128~127
2.3.6 练习六
#include <stdio.h>
unsigned char i = 0;
int main()
{
for (i = 0; i <= 255; i++)
{
printf("hello world\n");
}
return 0;
}
运行结果为死循环(无符号char 加到256时为0)
3. 浮点型在内存中的存储
3.1 浮点型存储例子
#include <stdio.h>
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 *pFloat的值为:0.000000 num的值为:1091567616 *pFloat的值为:9.000000
?这个例子可以充分证明:浮点型和整型在内存中的存储完全不同。
3.2 浮点数存储规则
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:(-1)^S * M * 2^E
- (-1)^S表示符号位,当S=0,表示V为正数;当S=1,V为负数。
- M表示有效数字(大于等于1,小于2)
- 2^E表示指数位
如 5.5 这个十进制浮点数,转化为二进制则为 101.1 ()
根据IEEE规定,则为:,得:S = 0, M = 1.011, E = 2
对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,接着11位是指数E,剩下的52位为有效数字M。?
IEEE 754对有效数字M和指数E的特别规定:
M:由于 1 ≤ M<2?,因此 M 只存储小数点后面的位数(小数点前面默认为1)
E:是一个无符号整型,在存入内存时需要先加一个数(8bit为+127,11bit为+1023)
|