1. long double
2. 空类型:void表示空类型(无类型),通常应用于函数的返回类型、函数的参数、指针类型。
void test(void)
{
}
int main()
{
return 0;
}
其中 void test(void) 中第一个 void 值该函数无返回值,括号中的 void 指的是不需要传参。
3.为什么数据在内存中是补码?
a、CPU中只有加法器;
b、减法就是加一个负值
c、原码计算:1-1
1: 00000000000000000000000000000001
-1: 10000000000000000000000000000001
和: 10000000000000000000000000000010
但此时和为-2,结果错误。
d、补码计算:1-1
1: 00000000000000000000000000000001
-1: 1111111111111111111111111111111111111(补码)
和: 100000000000000000000000000000000(和前边多了一位)
此时和的第一位会被丢弃(因为存储的是32位),和是0。
e、还与硬件有关,暂未深入研究
4.无符号数的打印是用%u
5.大端和小端(大小端字节序存储)
首先:如,0x11223344 这个数字,44是最低位的数字,11是最高位的数字。
a、大端:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中,
b、小端:是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。
c、使用程序来判断是大端还是小端
#include <stdio>
int main()
{
int a=1;
char* p=(char*)&a;
if(*p==1)
{
printf("小端 \n");
}
else
{
printf("大端\n");
}
}
几道例题
例1、
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n",a);
return 0;
}
此代码输出的数是一个很大的数;
因为:首先将-128这个整形数字放入char类型的变量中去
10000000000000000000000010000000(-128的原码)
1111111111111111111111111111011111111(反码)
111111111111111111111111111110000000(补码)
10000000(此时发生截断)
%u打印无符号整数,打印时又会发生整形提升;
111111111111111111111111111110000000
因为打印的是无符号数,所以原码反码和补码相同,故,上边的数就是打印出来的数
例2、
#include <stdio.h>
int main()
{
char a = 128;
printf("%u\n",a);
return 0;
}
128的原、反、补码相同,是:
10000000000000000000000010000000
存储时发生截断,
100000000
打印时整型提升
111111111111111111111111111110000000
所以答案与上边一样
例3、
#include <stdio.h>
int main()
{
unsigned int i;
for(i = 9; i >= 0; i--)
{
printf("%u\n",i);
}
return 0;
}
此代码是一个死循环;
因为 unsigned int 类型没有小于 0 的数,当 i = 0 时, i-- 又变成了无符号整形中的最大值
例4、
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
此时的 char 是 signed char ,取值范围是 -128~127,而for循环中从 -1 到 -128时正常运行,当 i = 129 时,此时存在char中的值是 127 ,并且在 char 中存储的数字会依次减小,当 i = 256时,char 中存储的数据为 0 。
例5、
#include <stdio.h>
unsigned char i = 0;
int main()
{
for(i = 0;i<=255;i++)
{
printf("hello world\n");
}
return 0;
}
此时是死循环
6.浮点数在内存中的存储
a、两个文件:float.h 定义了浮点数的取值范围的相关信息;
limits.h 定义了整型数的取值范围的相关信息。
b、存储规则:
任意一个浮点数 V 都可存储为:
(-1)^S * M * 2^E
(-1)^S 表示符号位,当S=0,V 是正数,当S=1,V 是负数
M表示有效数字,大于等于1,小于2;
2^E 表示指数位
例:
5.5
101.1 (二进制表示)
(-1)^0 * 1.011 * 2^2 (使用上述规则表示)
c、在内存中的存储
浮点数存储存的是S、M、E三个值;
float:
对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
double:
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
注:
a、M 是一个二进制的数,所以它的大小只可能在 1 ~ 2 之间,所以在存储 M 时,只存小数点后边的数字,读取的时候再把前边的 1 加上去;
b、
(1)E的存入,E 是一个无符号数,8位(float)时,取值范围是0~255;11位(double)时,取值范围是0~2047,但是科学计数法中的E可能是负数,所以在存入时, E 真实值需要加一个中间数,即8位(float)中间值 127 ,11位(double)中间值 1023 。
(2)E的读取,当E不全为0或不全为1时,E的计算值(内存中的值)减去127(或1023),得到真实值,再将有效数字M前加上第一位的1;E全为0时,E=1-127(或1-1023);E全为1时,表示的数是正负无穷大。