文章目录
前言
一、数据类型介绍
1.整型家族
注意:
int n与signed int n同义。
除char外,其他整型家族与上面一样。
2.浮点数家族
float和double
3.构造类型(自定义类型)
数组类型 int [20],其中数组元素是变化的,而每次变化类型就不同,因此是自定义类型。
4.指针类型
5.空类型
二、数据在内存中存储
1.原码,反码,补码
原码:直接将数值翻译成二进制序列。如果是负数,最高位是符号位1。
反码:正数与原码相同,负数将原码的符号位不变,其他位按位取反。
补码:正数与原码相同,负数反码+1得到补码
2.数据内存存储补码
1.对于整形来说,数据存放内存中存放的是补码。
计算机中没有减法,而只有补码能相当于实现减法运算。补码能将符号位与数值位统一进行处理。补码和原码和反码也能够相互转换。
如:1+(-1)=?
0000000000000000000000000001 1的补码
11111111111111111111111111111111 -1的补码
0000000000000000000000000000 相加,由于进位,最前面的1超出32位 不能保留,结果为0。
3.大小端介绍
地址排序: 低 -------》 高
11 22 33 44 注意:最左位为最高位,最右位为最低位。
大端(字节)存储:把数据高位字节的内容存低地址,把低位存高地址
小端(字节)存储:把数据高位字节的内容存高地址,把低位存低地址
x86是小端模式。
题目扩展
设计一个程序来判断当前机器是大端还是小端。
方一:
(char*):强制类型转换。之后只可以访问第一个字节,及第一个低字节。
int main()
{
int a = 1;
char* p = (char*)&a;
if (1 == *p)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
方二:用函数:
方一:
int check_sys()
{
int a = 1;
char* p = (char*)&a;
if (*p == 1)
return 1;
else
return 0;
}
方二:简化版函数:
int check_sys()
{
int a = 1;
return *(char*)&a;
}
int main()
{
int ret = check_sys();
if (1 == ret)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
4.整行的内存存储
1.char 类型会对整数进行截断,只取后面一个字节。
2.但%d打印有符号整数,对截断后进行整型提升的数被认为是补码要转化为原码按照原码输出。
3.%u打印无符号整数,对截断后进行整型提升的数直接当成原码,直接输出。
4.整型提升:如果原来是有符号类型提升前面全加1,是无符号类型整型提升前面全加0。
题目扩展1
详解:
int main()
{
char a = -1;
//-1 是整数,32bit
//10000000000000000000000000000001
//11111111111111111111111111111110
//11111111111111111111111111111111
//11111111 - a 截断
//11111111111111111111111111111111 - 提升 a的原码为-1
//
signed char b = -1;
unsigned char c = -1;
//10000000000000000000000000000001
//11111111111111111111111111111110
//11111111111111111111111111111111 b的原码为-1
//00000000000000000000000011111111 c无符号,原码和补码相同,为225
//
// -1 -1
printf("a=%d,b=%d,c=%d", a, b, c);
//%d是打印有符号的整数
//
return 0;
}
若此题打印printf(“%u”,b);则输出结果应该为:11111111111111111111111111111111的十进制数。
2.char如果是有符号类型的,那么第一位为符号位,其范围为:0~ 127,-128~ -1。
如果是无符号类型,则其范围为:0~225.
char类型就像这一个圆盘一样。
图圆:
题目扩展2
Sleep()与头文件#include<window.h>配合使用,可间隔打印显示在屏幕中的数据。
因为i–到最后一个判断时,i已经减到了0以后。但是由于此数是无符号整形,则不会为-1,而是变成全1.自然会输出一个特别大的数字。请注意看图圆。
5.浮点数的内存存储
浮点数可以表示为:(-1)^ S M2 ^E.
(-1)^S表示符号位,当S为0,为正数;S为1,为负数。
M表示科学计数法后的有效数字。范围一定在1~2
2^E表示指数位。
浮点数只存储S,M,E。
IEEE 754规定:
1.float的存储模型:(4字节)
2.double存储模型:(8字节)
对于64位浮点数,最高一位是符号位s,接着11位是指数E,剩下52位为有效数字M.
对于符号位s的存储方式是直接存储s的值存在第一位。
对于M的存储方式是存储科学计数法小数点后的数据。由于小数点前永远是1,因此只用取出时加上即可,不存。
对于E的存储方式是如果E不为全0或全1。把E加上127(1023)再储存,防止为负数。取出时减去127(1023)得到真实值,再将有效数字M前加上第一位的1。
如果E为全0,有效数字M不再加上1,为无穷小。
如果E为全1,表示±无穷大(±取决于s)。
题目扩展
解析:
int n=9;
整数存法:00000000000000000000000000001001 9的补码
浮点数存法:0 00000000 00000000000000000001001
E为全0,因此答案约为0.
(-1)^0 * 0.00000000000000000001001 * 2^-126
float f = 9.0;
化成二进制:1001.0
化为二进制科学计数法模式:(-1) ^ 0 * 1.001 *2^3
s = 0,e = 3,M = 1.001
浮点数存法:0 10000001 01100000000000000000000
整数存法:0100 0001 0001 00000000000000000000
大端地址:0x41 10 00 00