前面我们已经学习了基本的内置类型,现在咱们基本归类一下
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 *p;
char *p;
float *p;
void *p;
一个变量的创建是要在内存中开辟空间的。
空间的大小是根据不同的类型而决定的
例如:
int a = 10;
计算机中的整数有三种2进制表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”而数值位
正数的原、反、补码都相同。
负整数的三种表示方法各不相同
原码
直接将数值按照正负数的形式翻译成二进制就可以得到原码。反码
将原码的符号位不变,其他位依次按位取反就可以得到反码。补码
反码+1就得到补码。
整数在内存中存储的形式都是用补码
之前的操作符的详解中详细的讲过正数和负数在二进制的表示,下面有链接
链接: 操作符详解
我们可以看到下面图片中 a 和 b 分别存储的是补码,是以十六进制显示的
但是我们发现顺序有点不对劲,为什么呢

大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址
中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地
址中。

写一个程序来判断当前编译器的字节序

int main()
{
int a = 1;
char* b = (char*)&a;
if (*b == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
请问输出的结果是什么?
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.题解:


想一想输出的结果是什么?
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n",a);
return 0;
}
题解:

下面代码的结果是什么
int main()
{
char a = 128;
printf("%u\n",a);
return 0;
}
题解:

有人就想问 char 类型能放的下这么大的数字吗
char类型的取值范围是 127 到 -128
127加1 得到的是 -128, -1+1 = 0
正如下面的圆环:
当超出 char 类型存储的大小时,-128-1得到 127,如此循环

下面代码的结果是什么
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
return 0;
}
题解:

下面代码的结果是什么
#include<windows.h>
int main()
{
unsigned int i;
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
Sleep(1000); //休眠1000毫秒
}
}
题解:

下面代码的结果是什么
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
题解:

下面代码的结果是什么
#include <stdio.h>
unsigned char i = 0;
int main()
{
for(i = 0;i<=255;i++)
{
printf("hello world\n");
}
return 0;
}
题解:

常见的浮点数
3.1415
2.5
科学记数法
1E10 相当于1.0*10的10次方
浮点型和整形在内存中存储的方式是不一样的
先看一个例子:

解析:

n 和 *p 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?
要理解这个结果,一定要理解 浮点数在计算机内部的表示方法。
浮点型在内存中存储是由 IEEE 754 规定:
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
- (-1)^S * M * 2^E
- (-1)^ S表示符号位,当S=0,V为正数;当S=1,V为负数。
- M表示有效数字,大于等于1,小于2。
- 2^E表示指数位。
例如:
- 浮点数: 5.5
如果吧 5.5 的二进制转换成科学记数法的形式
科学记数法的形式 101.1 = 1.011
十进制的小数点向左移动了一位,相当于2的1次方
科学记数法的 1.011 相当于小数点向左移动了二位,相当于2的2次方
科学记数法: 1.0112^2
就可以写成:(-1)^ 0 * 1.0112^2
**那么,按照上面V的格式:S = 0 M=1.011 E =2
- 浮点数:-5.0
二进制是 -101.0
科学记数: -1.01×2^2
S=1,M=1.01,E=2**
- 浮点数:9.5
二进制:1001.1
科学记数:1.00112^3
(-1) ^0 * 1.00112^3
S = 0 M = 1.0011 E = 3
IEEE 754规定:
对于32位平台的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。

对于64位平台的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M

IEEE 754对有效数字M和指数E,还有一些特别规定
EEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1
因此可以被舍去,只保存后面的xxxxxx部分
比如保存1.01的时候,只保存01,等到读取的时候,
再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位
将第一位的1舍去以后,等于可以保存24位有效数字。

指数E从内存中取出还可以再分成三种情况:
E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将
有效数字M前加上第一位的1。
下面的二种条件很少出现,就简略写一点
E全为0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值
有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数
这样做是为了表示±0,以及接近于0的很小的数字。
E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)
让我们回到最开始的问题:
