learn_C_deep_5 (温故知新、sigend char a = -128的深度理解、unsigned int类型的写法规范)

目录

温故知新

理解"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 : 一元负运算符应用于无符号类型,结果仍为无符号类型,

猜你喜欢

转载自blog.csdn.net/qq_64446981/article/details/130298093