目录
温故知新
理解"unsigned int a = -10;"
如何理解大小端
大小端的概念
大小端是如何影响数据存储的
sigend char a = -128的深度理解
10000000为什么是-128,而不是-0
代码练习
unsigned int类型的写法规范
温故知新
理解"unsigned int a = -10;"
继上章之后,我们首先来复习一下"unsigned int a = -10;"的知识。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
unsigned int a = -10;//编译无错误
//-10转为二进制
//原码:1000 0000 0000 0000 0000 0000 0000 1010
//反码:1111 1111 1111 1111 1111 1111 1111 0101
//补码:1111 1111 1111 1111 1111 1111 1111 0110
//将二进制序列1111 1111 1111 1111 1111 1111 1111 0110 - 存到空间
//再看类型为无符号整形,不看符号位,直接补码就是原码
//1111 1111 1111 1111 1111 1111 1111 0110 - 4294967286
printf("%u\n", a);//4294967286
unsigned char b = -10;
//将二进制序列1111 1111 1111 1111 1111 1111 1111 0110 - 存到空间
//再看类型unsigned char
//发生截断
//1111 0110
//再看类型为无符号char类型, 不看符号位, 直接补码就是原码
//1111 0110 - 246
printf("%u", b);
return 0;
}
再来复习一下大小端的知识
如何理解大小端
可以通过模拟内存中存放二进制数的方式来理解大小端。假设我们要在内存中存储一个16位的二进制数0x1234,即十进制的4660。在大端字节序中,将最高位的字节存放在了最低的内存地址中,最低位的字节存放在最高的地址中,因此,在内存中,该二进制数的存储方式如下:
```
地址 内容
0x00 0x12
0x01 0x34
```
可以看到,0x12存放在了最低的地址0x00中,0x34存放在了最高的地址0x01中。而在小端字节序中,将最低位的字节存放在了最低的内存地址中,最高位的字节存放在最高的地址中,因此,在内存中,该二进制数的存储方式如下:
```
地址 内容
0x00 0x34
0x01 0x12
```
可以看到,0x34存放在了最低的地址0x00中,0x12存放在了最高的地址0x01中。
因此,可以理解为,大小端字节序是指在内存中存放二进制数时,每个字节的存放顺序不同。在大端字节序中,高位字节在前,低位字节在后;而在小端字节序中,低位字节在前,高位字节在后。这两种字节序会对数据的存储和传输产生影响,因此在不同的硬件和软件平台上需要注意字节序的问题。
大小端的概念
大端字节序(Big Endian)即高位字节优先,它将最高位的字节存放在最低的内存地址中,最低位的字节存放在最高的地址中,这和我们读数字的顺序一致,即最高位在最左侧,最低位在最右侧。
小端字节序(Little Endian)即低位字节优先,它将最低位的字节存放在最低的内存地址中,最高位的字节存放在最高的地址中,这和我们习惯的书写顺序一致,即从左向右依次写数字。
大小端是如何影响数据存储的
sigend char a = -128的深度理解
10000000为什么是-128,而不是-0
在使用补码表示法时,10000000表示的是负数,而不是-0。这是因为在补码表示法中,正数的二进制表示与原码表示相同,负数的二进制表示则为其绝对值的原码取反再加1。因此,10000000的补码为11111111(取反)+ 1=10000000,表示的是-128,而不是-0。在补码表示法中,-0没有意义,并且不存在对应的二进制表示。因为0的原码、反码和补码都是00000000,而且补码中没有正零和负零之分。因此,在补码表示法中,所有二进制表示的最高位(符号位)为1的二进制数都表示负数,而不表示-0。
代码练习
接下来我们看几个代码,看看我们是否掌握了上面的知识。
#include<stdio.h>
int main()
{
char a[1000];
int i = 0;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a));
return 0;
}
这个图能更方便我们了解char数据类型的取值,它是一个圈 (-1) -> (-128) -> 127 -> 0 -> (-1).
#include<stdio.h>
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
printf("%u\n", i + j);
return 0;
}
#include<stdio.h>
#include<windows.h>
int main()
{
unsigned int i = 0;
//死循环
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
Sleep(1000);//休眠一秒
}
return 0;
}
现在自己试着画图解释一下这个代码哟!
#include<stdio.h>
#include<windows.h>
int main()
{
unsigned int i = 0;
//死循环
for (i = 0; i >= 0; i++)
{
printf("%u\n", i);
Sleep(1000);//休眠一秒
}
return 0;
}
答案在后面。
unsigned int类型的写法规范
使用unsigne int类型时,建议初始化的时候,在数值后面加’u‘
例如:
unsigned int a = 10u;
因为如果unsigned int a = -10;编译器是不会报错的,但是这样unsigned int a = -10u;就会报错:error C4146 : 一元负运算符应用于无符号类型,结果仍为无符号类型,