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

简介: learn_C_deep_5 (温故知新、sigend char a = -128的深度理解、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 : 一元负运算符应用于无符号类型,结果仍为无符号类型,

相关文章
|
2月前
|
数据采集 分布式计算 数据处理
Dataphin常见问题之与指定类型int不兼容如何解决
Dataphin是阿里云提供的一站式数据处理服务,旨在帮助企业构建一体化的智能数据处理平台。Dataphin整合了数据建模、数据处理、数据开发、数据服务等多个功能,支持企业更高效地进行数据治理和分析。
|
2月前
|
SQL 流计算 OceanBase
OceanBase CDC从热OB库采集过来的Tinyint(1)类型会默认转换成Boolean,请教一下,如果想转换成int类型,有什方法么?
【2月更文挑战第25天】OceanBase CDC从热OB库采集过来的Tinyint(1)类型会默认转换成Boolean,请教一下,如果想转换成int类型,有什方法么?
30 3
|
2月前
|
存储 编译器 C语言
c语言中char的作用类型
c语言中char的作用类型
35 0
|
2天前
|
SQL 关系型数据库 MySQL
unsigned int 虽然mysql支持,但是不建议使用,因为可能在未来某个版本删除
unsigned int 虽然mysql支持,但是不建议使用,因为可能在未来某个版本删除
10 2
|
4天前
|
存储 关系型数据库 MySQL
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
本篇文章来讨论MySQL字段的字符类型选择并深入实践char与varchar类型的区别以及在千万数据下的性能测试
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
|
11天前
|
关系型数据库 MySQL Java
Java时间转换为MySQL中的INT类型时间戳
Java时间转换为MySQL中的INT类型时间戳
|
16天前
|
编译器 C++
C++_int负数转unsigned
C++_int负数转unsigned
20 0
|
18天前
|
C++
【C++】std::string 转换成非const类型 char* 的三种方法记录
【C++】std::string 转换成非const类型 char* 的三种方法记录
7 0
|
2月前
|
Python
Python系列(15)—— int类型转string类型
Python系列(15)—— int类型转string类型
|
2月前
|
存储 编译器 C语言
c语言中int的作用和类型
c语言中int的作用和类型
33 0