文章目录
- 整数存储
- 大小端
整数存储
在计算机中,整数都是通过二进制保存的,不论是十六进制还是八进制还是十进制
整数的2进制表⽰⽅法有三种,即原码、反码和补码
对于整形来说:数据存放内存中其实存放的是补码
- 在计算机系统中,数值⼀律⽤补码来表⽰和存储。
- 原因在于,使⽤补码,可以将符号位和数值域统⼀处理;
- 同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
正整数的反码补码就是它本身
但是负整数的反码补码不一样,以-1举例
int a = -1;
//100000000000000000000001 - 原码
// 原码->反码:除符号位,所有位取反
//111111111111111111111110 - 反码
// 反码->补码:反码加一
//111111111111111111111111 - 补码
因为负整数-1的补码存储形式,我们可以利用操作符~来判断输入是否成功
int a;
while (scanf("%d", &a) != EOF)//第一种
{;
}
while (~scanf("%d", &a))//第二种
{;
}
比如上面这个例子,我们往往会遇到要连续输入的情况,而我们会用上面这种方法来检验输入是否错误,但因为按位取反操作符~的存在,我们也可以利用下面这种方法。
为究其原因我们可以根据EOF的定义知道,EOF其实表示的是-1,就是因为这个的存在,意味着,如果第二种读取方法发生了错误,会返回一个-1,然后因为储存在计算机里的整形都是补码,再按位取反后,-1的补码11111111111111111111111111111111的32位1都会取反变成0,这样一来就阻止了while语句的进行
大小端
调试的时候,我们可以看到在a中的 0x11223344 这个数字是按照字节为单位,倒着存储的。这是为什么呢?
这是因为每个编译器都存在不同的大小端,比如这里的VS就是小端存储,低位字节内容44存在了数据的高地址处
其实超过一个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储,下面是具体的概念:
- 大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。
- 小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。
上述概念需要记住,方便分辨大小端。
之所以要有大小端是因为
这是因为在计算机系统中,我们是谈学掌的,个地都好应着一个字节,一个字节为8bit 位,但是在C语言中除了8 bit的 char 之外,还有16 bit的 short 型,32 bit的 long 型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
并且因为每个编译器的大小端存储方式不一样,就需要一种能够快速检查当前编译器是大端存储还是小端存储
有一年的百度面试题题就是这样的
请简述⼤端字节序和⼩端字节序的概念,设计⼀个⼩程序来判断当前机器的字节序。(10分)-百度笔试题
下面就是这道题的解决方法
注意的是,我们首先定义int a = 0x11223344;,是为了让a在计算机里存储,然后再通过char*类型提取出a的低位元素,通过判断即可得出结果。
int cheak()
{int a = 0x11223344;char* p = (char*)&a;if (*p == 0x11)return 0;return 1;
}
int main()
{int ret = cheak();if (ret == 1)printf("小端");elseprintf("大端");
}