程序员基本功,为什么你一定要懂16进制?

简介: 其实计算机需要的只是二进制,需要十六进制的是我们人

为什么你一定要懂16进制?

核心一句话:其实计算机需要的只是二进制,需要十六进制的是我们人


我们了解最基本的进制转换,但是想一下,是不是大多数都是基于数字之间的进制转换,比如常见的十进制和二进制互转,一般关于进制转换,有很多的在线工具,要去用:

image-20221123192218976

我们人看,就是数字66,但是计算机不行,它看不懂,你必须给它转换成它认识的,那就是二进制,也就是0和1组成的数据,所以我们看是66,计算机看就是1000010

所谓的X进制,就是逢x进一位,比如10进制,就是逢十进一,二进制就是逢二进一,那么16进制就是逢16进1了!

这是最基本的进制知识!


十六进制(简写为hex)在数学中是一种逢16进1的进位制。一般用数字0到9和字母A到F表示,其中:A-F相当于十进制的10-15,这些称作十六进制数字(重点记忆)。

例如十进制数57,在二进制写作111001,在16进制写作39。

不同电脑系统、编程语言对于16进制数值有不同的表示方式:

C语言、C++、Shell、Python、Java语言5及其他相近的语言使用前缀“0x”,例如“0x5A3”。开头的“0”令解析器更易辨认数,而“x”则代表十六进制(就如“O”代表八进制)。在“0x”中的“x”可以大写或小写。对于字符量C语言中则以x+两位十六进制数的方式表示,如xFF。

所以,理解16进制的一个关键,要知道什么是十六进制数,也就是组成十六进制的数据,(A-F,0-9),其中A-F相当于十进制的10-15,比如一个大写的A或者数字6就是一个十六进制数!

关于表示方式,我们可以记住最常见的形式就是其中最常用(或常见)表示十六进制数值的方式是将 '0x' 加在数字前

再次强化十六进制数,这个其实就是指的十六进制是有哪些基本元素组成的,实际上就是由我们知道的十进制数字0-9和10-15,你想一个,十六进制,就是逢16进1,就好比十进制逢10进一,那十进制基本数字区间就是0-9有10个数,而16进制其实就是0-15,总共有16个数,只不过超过9以后的10,11,12,13,14,15用大写字母A,B,C,D,E,F表示!

所以你可以再次思考下,无论16进制还是二进制,其实都是在我们熟知的十进制表示,比如二进制,就是逢2进1,包含两个数字0和1,而16进制就是逢16进1,包含16个数,就是0-15,不过为了表示方便,加以区分,16进制会在前面添加0x作为标识!

比如一个数字9,这样大家都会认为是十进制数字9,如果是0x9大家就知道这是16进制了,0x指定它是16进制,9是这个16进制的本体,那么16进制的0x9转换成二进制其实就是对本体的9做转换,而这个9就是十进制的9,转换成二进制就是1001,所以十六进制数字9对应的二进制为1001。


16进制中的每个数字用4个bit存储,所以,一个byte就可以存储两个16进制数,比如16进制0x9就是一个9,使用4bit存储,每个bit上存储的要么是0要么是1,所以16进制的数字9对应的二进制是1001,那么16进制的19对应的二进制则是1 1001,而16进制的119对应的二进制则是1 0001 1001!(要了解,这完全得益于一个十六进制数用4bit存储)

但是如果是十进制的话,就没那么快算出二进制了,比如十进制数字9的二进制是1001,那么十进制数字19的二进制呢?十进制数字119的二进制呢?是不是有点费劲,需要计算一番才行?

因此,你会发现,16进制和二进制之间转换是比十进制和二进制之间的转换容易的

那为什么16进制与二进制的转换就容易许多呢?

主要还是那个十六进制的每个数用4bit存储,再说的细一点就是16是2的整数次幂,而10不是,因此,16进制转二进制就要比10进制转二进制容易!

接着需要了解的就是为啥16进制用的比较多,很重要,得记住?、

  1. 我们需要找一个与二进制转换比较友好的(必须是2的整数次幂),可以理解成16进制是刚刚好的那个值,再往上32进制可读性差,我们记起来费劲,往后八进制表达的内容不如16进制多
  2. 由于一个字节有8bit,而一个16进制数是一个字节的一般,两个16进制数刚好1字节

所以啊,16进制就是刚刚好的那一个!

到了这里,我们就学到了一个新的表述数据的方式,就是16进制,就是用0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15这16个数去表示的一种数据格式,当然,为了简洁表示,把10,11,12,13,14,15用字母A,B,C,D,E,F表示,所以所谓的16进制数据就是由0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F这16个元素去表示的,每一个元素被称为一个16进制数,然后还要记住的就是一个16进制数用4个bit去表示,也就是一个16进制数占0.5个字节,2个16进制数据刚好占1个字节

数据存储都是需要转换为2进制加载进内存,所以你如果要存储一个16进制数,那么就要把16进制数转换为2进制才行,怎么转,就是根据一个16进制数占0.5个字节(4bit)去转换,比如16进制数0x19,要注意0x是个标识,代表是一个16进制的19,而不是十进制的19,然后根据每个16进制数用4个bit存储,这里有两个16进制数就是1和9,也就是总计用8个bit去存储,画个图也就是这样:

image-20221123230600535

每一格代表1bit的空间,这里有8bit,接下来就是把16进制数据0x19存进去,分别把1和9转换成2进制,9是1001:

image-20221123230843401

1还是1:

image-20221123231029089

就这样,16进制数据“0x19”占据了一个字节,8bit的空间!再举个例子,比如16进制数据0xA9,它的存储如下:

image-20221123231503901

你看这个16进制数A对应的就是十进制的10,而十进制的10对应的二进制就是1010,也就是说,所谓的16进制就是由0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F这16个元素(16进制数)自由组合的数据,如果要存储16进制的话,就是把每一个16进制数作为10进制转换成2进制后存储在内存中,每一个16进制数占据0.5个字节,也就是4bit!

为什么用4bit存储呢?因为最大的16进制数就是F对应的十进制就是15,而15对应的二进制就是1111,刚好4bit够用!

OK,到了这里,你需要清晰明了的懂以下两个知识点了:

  1. 16进制是怎么表示的?
  2. 16进制如何存储的?

接着,我们要聊内存地址!切记,当我们聊内存的时候,你就把各个进制的数据该如何存储这么一回事忘掉,比如16进制如何存储的就和我们要聊的内存地址毫无关系!

OK,那我们开始内存地址的学习~

我们经常说内存啊,硬盘啊这些,其实都是存储设备,就是可以存储数据的,你平常写的程序代码这些,无论你是用记事本写的,还是用IDE工具写的,刚开始都是存储在硬盘上,也就是你电脑上的C盘,D盘这些,桌面就是在C盘,这些数据只要你写好保存好,不管你关机还是开机,数据一直都在不会丢失!

硬盘空间大,可以存储的东西多,但是它数据传输比较慢,因此,程序要想执行起来,必须把相应的数据加载进内存(比硬盘快很多)中才行,要从内存中把数据在交给CPU进行执行处理!

那这个时候,你就得想,无论你这个程序数据是刚开始存在硬盘上还是需要运行的时候加载进内存中,那么内存和硬盘都要有地址,为啥?因为他们得存储数据,就得把一定的空间分配给这些数据进行存储,那么每个空间就得有地址,只有地址,才能找到这些数据,就好比,你买快递得提供你的收货地址,没有收货地址,就找不到你,也给你送不了货啊!

因此,我们程序中的每一个数据,在内存上都会有一个对应的地址,就是为了后面用到可以找到它

另外还要清楚的就是,这个地址是计算机做的事情,它会把所有的数据加载进内存,然后给这些数据编好地址,哪个数据在哪,计算机都知道,所以内存地址这个东西就是给计算机看的,而我们看的则是引用(针对java来说)

重点来了:

计算机内存中最小的单位是bit,最基本的单位是字节,1字节(byte)= 8位(bit)

为什么最小的单位是bit呢?因为数据是要转换成0和1组成的二进制数据进行存储,那么一个0或者一个1就刚好占据1bit,而1bit表示的太少,就以1字节也就是8bit为最基本单位:

image-20221123232629226

这个时候就有个非常重要的知识了,我们前面说了,你把数据存储在内存中,需要有个地址,方便后续找到该数据,因此就有了内存地址这么一说,相当于一间屋子的门牌号,比如上述表示的8bit空间存储的就是16进制数据0xA9,这个时候我得给这个空间编个号,也就是给个地址,后续通过这个地址好找到这个数据~

怎么编号呢?注意了,我们使用16进制给内存地址编号,不要走神了,更重要的是,我们把8bit也就是1字节作为一个内存地址,也就是按字节编址,什么意思呢?

比如我们要分苹果,8个苹果装1筐,那就是每筐有8个苹果,然后就会这样编号(按筐编号):

image-20221123233642993

这个时候你就知道了,编号1的一筐里面8个苹果,编号加一也就是编号2就是下一筐了,里面也是8个苹果……这就是所谓的按筐编号

接着看我们的按字节寻址,我们把1字节(一筐)作为一个内存地址,也就是8bit(一筐苹果),然后用16进制去编这个号:

image-20221123234742367

这个时候,我们如果找到0x0001这个内存地址,就找到了这块内存空间:

image-20221123234826827

也就是1个字节,8bit的大小,取出里面的数据10101001,这是二进制的,转换成16进制就是0xa9或者0xA9(大小写都行)!

OK,以上看完,你就要明白用16进制按字节编址是怎么回事了!

目录
相关文章
|
监控 druid Java
Spring Boot 3 集成 Druid 连接池详解
在现代的Java应用中,使用一个高效可靠的数据源是至关重要的。Druid连接池作为一款强大的数据库连接池,提供了丰富的监控和管理功能,成为很多Java项目的首选。本文将详细介绍如何在Spring Boot 3项目中配置数据源,集成Druid连接池,以实现更高效的数据库连接管理。
13714 2
Spring Boot 3 集成 Druid 连接池详解
|
数据格式
一文读懂A2L文件和ASAP2 Studio的使用
一文读懂A2L文件和ASAP2 Studio的使用
一文读懂A2L文件和ASAP2 Studio的使用
|
存储 固态存储 数据库
SSD接口选择指南:PCIe与SATA性能大比拼
【4月更文挑战第21天】
3823 0
|
7月前
|
人工智能 安全 网络安全
智防共生,守御无界——AI与网络安全的双向博弈与协同发展
人工智能技术的迭代升级,正深刻重塑网络安全的攻防格局,呈现“赋能防御”与“催生威胁”的双向效应。AI既为破解传统网络安全的痛点提供了智能解法,大幅提升防御效率与精准度,也被恶意利用,催生了更具隐蔽性、自主性的网络攻击手段。
|
10月前
|
人工智能 监控 JavaScript
CRM系统销售管理全流程解析:从MTL到RMS的数字化转型指南
在数字化转型浪潮下,CRM系统中的销售管理已成为企业增长的核心引擎。纷享销客以“全流程覆盖+智能化驱动+行业化适配”为核心,构建涵盖MTL、L2O、CPQ、RMS的端到端销售闭环,并深度融合AI技术,打造销售Agent生态,实现线索转化、客户洞察、报价履约等全场景智能赋能。通过MCR大客户管理体系,推动从短期成交向长期价值经营转型。其三层架构支持灵活定制与生态集成,已在智能制造、食品饮料、医疗健康等行业落地,助力神策数据、拓斯达、一舟股份等企业实现销售效率与战略协同的双重提升。未来,销售管理将迈向更智能、更协同、更个性化的新阶段,纷享销客持续以AI驱动企业可持续增长。
|
存储 Linux Android开发
Android底层:通熟易懂分析binder:1.binder准备工作
本文详细介绍了Android Binder机制的准备工作,包括打开Binder驱动、内存映射(mmap)、启动Binder主线程等内容。通过分析系统调用和进程与驱动层的通信,解释了Binder如何实现进程间通信。文章还探讨了Binder主线程的启动流程及其在进程通信中的作用,最后总结了Binder准备工作的调用时机和重要性。
1060 0
Android底层:通熟易懂分析binder:1.binder准备工作
|
存储
如何理解结构体的浅拷贝与深拷贝
结构体的浅拷贝仅复制对象的引用或基本数据类型值,不创建新对象;深拷贝则会递归地复制所有对象及其引用的对象,形成完全独立的新对象。两者主要区别在于是否共享内部对象。
|
数据库 开发者 Python
"揭秘FastAPI异步编程魔法:解锁高性能Web应用的终极奥义,让你的并发处理能力飙升,秒杀同行就靠这一招!"
【8月更文挑战第31天】FastAPI是一款基于Python的现代化Web框架,内置异步编程支持,可充分利用多核CPU的并行处理能力,大幅提升Web应用的性能。本文探讨FastAPI的异步编程特性,通过示例代码展示其在处理并发请求时的优势。异步编程不仅提高了并发处理能力,还降低了资源消耗,使代码更简洁易读。无论对于初创企业还是大型企业级应用,FastAPI都是构建高性能Web服务的理想选择。
848 0
|
数据可视化 数据挖掘 定位技术
Python+Kepler.gl轻松制作时间轮播地图
Python+Kepler.gl轻松制作时间轮播地图
464 1
|
设计模式 程序员 C#
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
2032 0

热门文章

最新文章