【C语言】八进制、十六进制

前言

在我们日常生活中使用的数往往是十进制的,而当我们学习C语言后我们会接触到许多不同的进制并且时常需要去思考与使用这些不同的进制(尤其是2的幂相关的进制,因为这种计数系统比十进制更接近于计算机的二进制系统),所以学习和掌握这些不同进制是非常重要的。

本文将对八进制和十六进制(8和16都为2的幂)进行一些讲解。

通常情况C语言都假定整型常量是十进制的数,但在表达与计算机相关的值时,八进制和十六进制却十分方便。

十六进制,与二进制的转换

十六进制(hexadecimal或hex),是基于16的幂的计数系统。用0~15表示数,但是当数字有两位,如10、11时会产生歧义,指的是1和0还是10呢?所以我们用字母A~F来表示10~15的数,10表示为A,11即B,12即C,13即D,14即E,15即F。例如,十六进制数A3E(在C中写作0xA3E)其实是10 3 14,转化为对应的十进制数时也就是各个位去乘各个位的权重:10*16^2+3*16^1+14*16^0 = 2622。

当然,A~F也可以写成小写的字母,a~f。0xA3F == 0xa3f。

有一个非常重要的规律是:十六进制数的每一位数恰好由4位二进制数表示,或者说每一个十六进制位可以翻译为4个二进制位。

举例:十六进制的2可以表示为0010,十六进制6则是0110,所以十六进制数26的位组合(bit pattern)就是00100110,十六进制数63的位组合就是反过来,即01100010。

可以在计算器上证明一下(HEX即hexadecimal,十六进制;BIN即binary system,二进制):

可以看到这么转化的结果确实正确,是不是非常方便?

每个十六进制位都对应一个4位二进制数(即4个二进制位),所以两个十六进制位恰好对应一个8位二进制位,也就是一个字节。第1个十六进制位表示前4位,第2个十六进制位表示后4位。

由此,十六进制位非常适合表示字节值。我们调试时的内存窗口的一个00就是一个字节,把00写在一起是为了更明确地表示这是两个十六进制位也就是一个字节(没有了解过的朋友可以先跳过):

比如下面这个代码,我们在内存窗口,地址处输入&m、把列数改为4,可以看到存放m的值的四个字节(m为一个int类型也就是4个字节

1d 08 00 00是8个十六进制位,两个写一起代表一个字节,正好是4个字节

(为什么1d 08 00 00对应的十进制是2077,这涉及到大小端字节序,本文按下不表)

00000000 00000000 00001000 00011101         

//2077的二进制序列

00011101 00001000 00000000 00000000         

//小端字节序存储形式

0001 1101 0000 1000 0000 0000 0000 0000     

//把4位放在一起刚好可以翻译一个十六进制位

1       d      0       8       0       0       0       0           

//翻译为十六进制

1d 08 00 00                                                         

//2位十六进制位放一起代表一个字节

 附图:

我们可以看到十六进制每位最大的数15,也就是F,等价二进制为1111,恰好是4个二进制位能表示的最大值,这也说明了我们最多需要4个二进制位就能表示一位十六进制数。

八进制,与二进制的转换

八进制(octal),是基于8的幂的计数系统。用0~7表示数字。如八进制的432(在C中写作0432),转化十进制即:4*8^2+3*8^1+2*8^0 = 282。

同样的,八进制与二进制之间也存在非常方便的转换方法,正如十六进制转换二进制一样。对于八进制来说,规律是每个八进制位对应3个二进制位。如,八进制的0277的二进制是10111111(更方便点看就是10 111 111)。用111转换0277的最后一个7,再用111转换0277倒数第二个7,最后用010转换2,而0277最前面的0只是八进制前缀(下面会说)。

附图:

我们可以看到八进制每位最大的数7,等价二进制为111,恰好是3个二进制位能表示的最大值,这也说明了我们最多需要3个二进制位就能表示一位八进制数。

表示进制的前缀

However,有一个问题:现在我们有一个数10000,我们可以说它是十进制、十六进制或者二进制,但是计算机会认为它是十进制、十六进制还是二进制呢?

所以在C语言中,我们用特定的前缀表示一个数是什么进制。0x或0X前缀用来表示十六进制数,举例来说17的十六进制表示是0x11或0X11

八进制的情况也是类似的,我们同样需要特点的前缀表示它是一个八进制数而非其他进制,我们采用的前缀是0,举例来说17的八进制表示为021。

我们需要记住的一点是,不同的进制只是服务于更方便的表示,不会影响数值被存储的方式。不管是写成17、 021还是0x11,这个数被存储的方式都是在计算机内部以二进制进行编码

显示(打印)八进制与十六进制

当我们要让一个数以我们想要的进制显示时,就需要使用对应的转换说明。不同进制有不同的转换说明。我们最常用的%d就是以十进制显示数字;八进制显示数字,用的是%o;十六进制显示,用%x。如果我们还想要更清楚地表明显示出来的数是什么进制就需要把前缀一起显示,而显示前缀也有转换说明:%#o、%#x分别为八进制和十六进制带前缀的转换说明。当然,也可以改为大写,%#X。

演示程序

最好的掌握方法就是上手写代码,现在我们不妨写一个程序,以十进制、八进制、十六进制打印同一个数,不妨就打印2077吧:

 到此,本文就结束了,祝阅读愉快^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/16070.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图解IO与Netty系列】IO的同步与异步、阻塞与非阻塞,Linux五种IO模型

IO的同步与异步、阻塞与非阻塞,Linux五种IO模型 IO的同步与异步,阻塞与非阻塞阻塞IO与非阻塞IO同步IO与异步IO Linux五种IO模型BIONIOIO多路复用信号驱动IOAIO IO的同步与异步,阻塞与非阻塞 我们有时会看到类似于同步阻塞式IO、同步非阻塞式…

(避坑)SpringSecurity关于使用.antMatchers放行接口不生效问题

问题 在使用SpringSecurity的时候发现放行指定接口一直没有生效,使用"/**"就可以生效的问题 关于securityConfig的配置代码 Beanprotected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.csrf().disable() // 关闭csrf防护…

博客开始使用 Cache Master 缓存插件

明月在给大家推荐 Cache Master 插件的时候(可参考【推荐个比较纯正的缓存插件——Cache Master】一文),仅仅是在其他站点上试用了一下,今天明月正式在博客上用上了 Cache Master,没有想到对 Dragon 主题的支持竟然是出…

Java中的泛型擦除(Type Erasure)详解

在Java编程中,泛型(Generics)是一个强大的工具,它允许程序员在编写代码时定义和使用类型参数,从而编写更灵活、可重用的代码。然而,Java的泛型实现有一个重要的特点,即类型擦除(Type…

RUST 和 GO 如何管理它们的内存

100编程书屋_孔夫子旧书网 Go 中的内存管理 Go 中的内存不会在缓存键被驱逐时立即释放。 相反,垃圾收集器会经常运行以发现任何没有引用的内存并释放它。 换句话说,内存会一直挂起,直到垃圾收集器可以评估它是否真正不再使用,而…

rtsp协议分析

rtsp概述 rtsp (real-time stream protocol)实时流媒体控制协议。RFC2326:这是RTSP的初始定义版本v1.0,由哥伦比亚大学、网景和RealNetworks公司提交给互联网工程任务组(IETF)作为RFC标准。RFC7826:这是RTSP的后续更新…

Java进阶学习笔记14——模板方法设计模式

面试和看源码。 谈到设计模式: 1、解决了什么问题? 2、怎么写? 模板方法设计模式解决了什么问题? 解决方法中存在重复代码的问题。 写法: 1)定义一个抽象类: 2)在里面定义两个方…

JAVA面试题大全(十五)

1、Zookeeper 是什么? zookper是一个分布式的,开放源码的分布式应用程序协调服务。是 google chubby 的开源实现,是 hadoop 和 hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护…

C# 控制台应用模板可生成顶级语句

C# 控制台应用模板可生成顶级语句 项目2024/01/0810 个参与者 反馈 本文内容 使用新的程序样式隐式 using 指令全局 using 指令使用旧程序样式 从 .NET 6 开始,新 C# 控制台应用的项目模板在 Program.cs 文件中生成以下代码: C#复制 // See https…

C++ prime 第五版 第14章 重载运算与类型转换

一、基本概念 重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成。和其他函数一样,重载的运算符也包含返回类型、参数列表以及函数体。 我们不能为内置类型的运算对象重定义运算符。对于一个运算符函数来说&…

某方protobuf闲谈

问题 当我们去看某方的时候,搜索了关键词svm,然后通过抓包查看,请求的Request Payload是一串看不懂的乱码,并且返回的数据也大部分是乱码 观察请求的Content-Type是application/grpc-web+proto,没错数据的传输是protobuf的形式了 protobuf的相关概念和原理,网上有很多教…

vulhub——Aria2、bash、catic

文章目录 一、Aria2 任意文件写入漏洞二、CVE-2014-6271(Bash Shell 漏洞)三、CVE-2022-46169(Cacti 前台命令注入漏洞) 一、Aria2 任意文件写入漏洞 Aria2是一个命令行下轻量级、多协议、多来源的下载工具(支持 HTTP…

conda create,conda:未找到命令,ubantu添加环境变量,make工具是什么,docker工具什么,

目录 conda create -n flock_client python==3.11 conda:未找到命令,ubantu添加环境变量 添加conda到系统路径

docker-compose 搭建 单机版ELK

docker-compose 搭建 单机版ELK 前言 本次部署将使用ElasticSearch官方的镜像和Docker-Compose来创建单节点的ELK,用于学习ELK操作。在k8s集群内,如果每天的日志量超过20G以上,建议部署在k8s集群外部,以支持分布式集群的架构。在…

Flutter 中的 RepaintBoundary 小部件:全面指南

Flutter 中的 RepaintBoundary 小部件:全面指南 在Flutter的高性能渲染体系中,RepaintBoundary是一个重要的优化工具。它允许开发者将复杂的组件分割成独立的部分,以减少不必要的重绘,从而提高应用的性能。本文将提供RepaintBoun…

11|数据库编程:包括数据库的基本概念,JDBC的使用,数据库连接池的实现,Hibernate和MyBatis的应用等。

数据库基本概念 想象你有一个装满宝藏的箱子,里面放着各种宝贝,但这些宝贝都按照一定规则摆放。数据库就像是这样一个箱子,但它存放的是信息,比如姓名、年龄、电子邮件等。它帮我们有条理地管理数据,让我们可以方便地…

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第26节-内嵌blender展厅

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第26节-内嵌blender展厅 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界…

python操作rabbitmq的consumer,并强制关闭特定consumer的连接

引入 python获取指定队列的consumer python可以使用rabbitmq_management的api获取所有consumer的信息。【队列需要安装rabbitmq_management,在大部分情况下,我们安装队列的同时,都会安装管理界面,以方便一些简单的手动操作与简单…

网络编程的基础知识(适合新手)

网络编程 在Java中,网络编程是指使用Java语言进行网络通信的编程技术。这种技术使得位于不同地理位置的计算机能够通过网络进行通信,实现资源共享和信息传递。 一、定义 Java网络编程是Java语言在网络通信方面的应用,它利用Java提供的网络…

位带操作 Bit-band

位带操作(Bit-banding)的特性是ARM Cortex-M微控制器中一个非常有用的功能,其目的是提供一种简便的方法来访问和操作存储器中单个位的状态。位带操作能够使程序员能够以原子操作(即不可中断的操作)的方式读取和写入单个…