debug版本内存分配由低到高,release版本会优化代码,内存开辟方式有所差异
long类型在32位4字节,64位8字节
1.整型家族
算数转换的数据级别(由高到低)
long double
double
long float
float
unsigned long int
long int
unsigned int
int
负数反码对源码符号位不变,其他按位取反,补码是反码+1
补码取反再+1也能得到源码
大小端字节序
大端字节序储存 正着放 低地址到高地址(高位字节序存放到低地址处)
小端字节序储存 反着放 高地址到地地址
存放 0x11223344
//大端字节序存储:
//11 22 33 44
//小端字节序存储:
//44 33 22 11
char (字符的本质是ASCII码值)
至于是以下哪个取决于编译器
1个字节
unsigned char 取值范围 :0~255signed char 取值范围 :-128~127
int main()
{
char a = -128;
//10000000000000000000000010000000
//11111111111111111111111101111111
//11111111111111111111111110000000
//a被截断成 10000000
//11111111111111111111111110000000 提升
printf("%u\n", a); //4294967168
//10000000000000000000000010000000 源码
printf("%d\n", a); //-128
a = 128;
//00000000000000000000000010000000
//10000000 a
//11111111111111111111111110000000
printf("%u\n", a); //4294967168
return 0;
}
int i = -20; //11111111111111111111111111101100 补码
unsigned int j = 10; //00000000000000000000000000001010 补码
//11111111111111111111111111111010 补码
//10000000000000000000000000001010 源码 符号位不变
printf("%d\n", i + j); // -10
看看下面代码输出什么
char arr[1000];
int i;
for (i = 0; i < 1000; i++)
{
arr[i] = -1 - i;
}
// char -128~127
//-1 -2 -3 ··· -127 -128 127 126 ···3 2 1 0
//
printf("%d",strlen(arr)); //255
//strlen只关注字符串中\0(ASCII码值就是数字0)之前出现多少个字符
以下均分为 unsigned , signed两种,并且默认signed
short
2个字节
int
4个字节 = 32bit
long
4 / 8个字节 //C语言只规定了sizeof ( long ) >= sizeof ( int )
long long
8个字节
2.浮点型家族
float
double
1E10 表示 1.0*10^10
不能用浮点型指针取整型
int n = 9;
float* pfloat = (float*)&n;
printf("%d\n", n); //9
printf("%f\n", *pfloat); //0.000000
printf("%d\n", *pfloat); //0
*pfloat = 9.0;
printf("%d\n", n); //1091567616
printf("%f\n", *pfloat); //9.000000
任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数
M表示有效数字,大于等于1,小于2
2^E表示指数位
float v = 5.0; // 二进制表示 101.0 -> 1.01*2^2 -> (-1)^0*1.01*2^2
float v2 = 9.5; //1001.1 = 1.0011*2^3
float v3 = 9.6; //无法精确保存
浮点数在内存中的储存情况
对于32位浮点数 (单精度浮点数)
对于64位浮点数 (双精度浮点数)
对于M的规定
保存M时,默认一个数的第一位总是1,因此可以被舍去,只保存后面的 xxxxxx部分
对于E的规定
存入内存时E的真实值必须再加上一个中间值
对于8位的E , 中间值是127
对于11位的E,中间值是1023
举例
float f = 5.5;
//101.1 = 1.011*2^2
//S=0 M=1.011 E=2 2(真实值)+127(中间值)=129
//内存中存放 0 10000001 01100000000000000000000000 小端存放 00 00 b0 40
指数E从内存中取出有特殊情况
E全为0
这时真实值很小(-126或-1022)
有效数字M不再加上第一位的1,而是还原为0.00000000xxxxxx的小数。
这样做是为了表示±0,以及接近于0的很小的数字。
E全为1
这时,如果有效数字M全为0,表示±无穷大
构造类型
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
指针类型
int * p;
char * p;
float * p;
void * p;
空类型
void
通常用于函数的返回类型、函数的参数、指针类型。
void tee()
{
}
void* p;
int test(void)
{
}
int a=test(1); //调用这个函数时传参也能执行