2023-10-16 itoa函数的局限以及实现


点击 <C 语言编程核心突破> 快速C语言入门


itoa函数的局限以及实现

  • 前言
  • 一、功能描述
  • 二、具体实现
    • 对于第一版, 实现如下:
    • 第二版实现:
    • 测试用例:
  • 总结


前言

把一个数用某种进制打印, 是一个很有用的功能,

值得庆幸的是, C语言有这么一个函数itoa(), 它可以把一个数转换为2至36进制的字符串,

但不那么幸运的是, 这个函数只是存在于某些编译器中, 比如Windows下的clang, 但Linux下, 则没有这个函数.

不过这也不是什么问题, 既然选择用C语言, 造轮子就是程序员的命运, 做个函数实现, 并不困难.


一、功能描述

itoa()函数需要传入三个参数,

一个无符号整数num, 基于num进行进制转换,

一个字符指针string, 为了安全, 至少需要33字节, 因为我们要实现一个转换32位的函数, 如果是2进制, 最大需要32位, 外加一个末尾0,

一个进制限制radix, 从2到36, 再多也可以, 但是意义不大.

函数返回赋值后的string字符指针, 因此函数原先应该是:

char *itoa(uint32_t num, char *string, uint32_t radix);

二、具体实现

对于第一版, 实现如下:

#include <stdint.h>
#include <string.h>char *itoa(uint32_t num, char *string, uint32_t radix)
{static char arr[40];arr[0] = '0';static int index;index = 31;while (num){static uint32_t numA;numA = num % radix;arr[index--] = (char)(numA > 9 ? numA - 10 + 'a' : numA + '0');num /= radix;}static char *rest;rest = arr + (index == 31 ? 0 : index + 1);strncpy(string, rest, 32 - index);return string;
}

但有两个问题可以进行改进,

其一, 进制限制没有判断, 如果是超过2至36的其它数则会出现比较奇怪的输出, 需要打个补丁.

其二, 基于效率, 字符转换用了三目运算, 这个可能比较吃效率, 需要优化.

第二版实现:

#include <stdint.h>
#include <string.h>char *itoa(uint32_t num, char *string, uint32_t radix)
{// 如果进制限制超出范围, 则返回空字符串if (radix < 2 || radix > 36){string[0] = '\0';return string;}// 如果num等于0, 则直接赋值为0, 返回if (num == 0){string[0] = '0';string[1] = '\0';return string;}// 建立一个buffer, 40的空间足够容纳所有转换字符static char arr[40];// 建立一个索引, 用于从后向前填充字符static int index;index = 31;while (num){// 直接通过数组引用赋值, 免去分支以及计算arr[index--] = "0123456789abcdefghijklmnopqrstuvwxyz"[num % radix];num /= radix;}// 这个函数的参数比较值得关注// arr + index + 1 是指向最后被赋值的字符位置的指针// 32 - index 是赋值字符数量 + 1 多一个字符位是给末尾0的strncpy(string, (arr + index + 1), (32 - index));return string;
}

实现中没有考虑到有符号的问题, 因为C语言中, 本身十六进制或二进制就没有符号,

当然, 如果有必要设计符号的转换, 也不难, 但函数的形参类型需要转换, 大家可以自己研究.

测试用例:

#include <stdint.h>
#include <stdio.h>
#include <string.h>char *itoa(uint32_t num, char *string, uint32_t radix);int main()
{char str[40] = "abcdabcdabcdabcdabcdabcdabcdabcdabcd";itoa(255, str, 16);itoa(8, str, 16);itoa(-1, str, 2);itoa(0, str, 2);itoa(0, str, 1);return 0;
}char *itoa(uint32_t num, char *string, uint32_t radix)
{// 如果进制限制超出范围, 则返回空字符串if (radix < 2 || radix > 36){string[0] = '\0';return string;}// 如果num等于0, 则直接赋值为0, 返回if (num == 0){string[0] = '0';string[1] = '\0';return string;}// 建立一个buffer, 40的空间足够容纳所有转换字符static char arr[40];// 建立一个索引, 用于从后向前填充字符static int index;index = 31;while (num){// 直接通过数组引用赋值, 免去分支以及计算arr[index--] = "0123456789abcdefghijklmnopqrstuvwxyz"[num % radix];num /= radix;}// 这个函数的参数比较值得关注// arr + index + 1 是指向最后被赋值的字符位置的指针// 32 - index 是赋值字符数量 + 1 多一个字符位是给末尾0的strncpy(string, (arr + index + 1), (32 - index));return string;
}

总结

设计一个可用的库函数比想象的还是要难一些, 需要考虑到很多问题, 兼容性, 可移植性, 效率, 以及使用者的理解, 从这一个小小的函数实现, 就可见难度之大, 所以说, 有时候认为自己设计的东西随便就能碾压库函数, 那可能是梦的深沉, 没有睡醒.


点击 <C 语言编程核心突破> 快速C语言入门


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

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

相关文章

前端代码优化之从系统区分处理的业务场景看如何优化代码中的if判断

最近有个三端统一的技术场景&#xff0c;主要是以前移动端的 hybrid 网页在不考虑 UI 适配的情况下、期望能够直接在 PC 客户端投放。在评估修改面的时候发现了一段可以深思的代码&#xff1a; if (platform iphone) {location.href iphoneClientUrl; } else {location.href…

Webpack和JShaman相比有什么不同?

Webpack和JShaman相比有什么不同&#xff1f; Webpack的功能是打包&#xff0c;可以将多个JS文件打包成一个JS文件。 JShaman专门用于对JS代码混淆加密&#xff0c;目的是让JavaScript代码变的不可读、混淆功能逻辑、加密代码中的隐秘数据或字符&#xff0c;是用于代码保护的…

LED显示屏高刷新率和低刷新率有什么区别

LED显示屏的刷新率是指图像在LED显示屏上更新的速度&#xff0c;也即屏幕上的图像每秒钟出现的次数&#xff0c;它的单位是赫兹&#xff08;Hz&#xff09;。LED显示屏的刷新率越高&#xff0c;图像闪烁感就越小&#xff0c;稳定性也就越高&#xff0c;换言之对视力的保护也越好…

图片批处理工具 PhotoMill X直装 for mac

PhotoMill X是一款强大的图像处理软件&#xff0c;它可以帮助用户快速地对照片进行编辑、调整和转换。它支持在单个或批量模式下处理大量的图像文件&#xff0c;并具有直观的用户界面和易于使用的工具。 PhotoMill X具有的功能有&#xff1a; 裁剪、缩放、旋转、调整明暗度、…

python+django学生选课管理系统_wxjjv

1&#xff09;前台&#xff1a;首页、课程信息、校园论坛、校园公告、个人中心、后台管理。 &#xff08;2&#xff09;管理员&#xff1a;首页、个人中心、学生管理、教师管理课、程信息管理、课程分类管理、选课信息管理、作业信息管理、提交作业管理、学生成绩管理、校园论…

国际伦敦银点差费值得吗?

伦敦银是国际轨技术属市场上广受追捧的白银保证金交易品种&#xff0c;具有交易时长、交易制度灵活、资金利用率高等诸多的优点。 国际伦敦银的优势主要来自它所实行的是保证金交易制度。目前香港平台一般执行的保证金比例标准是2%&#xff0c;以目前22美元/盎司左右的白银价格…

epiiAdmin框架注意事项

1&#xff0c;epiiAdmin文档地址&#xff1a; 简介/安装 EpiiAdmin中文文档 看云 2&#xff0c;项目性想新建模块 composer.json文件——autoload选项——psr-4下增加模块名称&#xff0c;然后执行composer update命令。 "autoload": {"psr-4": {"…

代理现货白银有什么手续

成为现货白银代理商的好处有很多&#xff0c;一方面打理依然可以像普通投资者那样&#xff0c;采用平台的交易服务&#xff0c;直接在市场上通过交易&#xff0c;赚取高杠杆所带来的高回报&#xff0c;另一方面还可以根据自己客户的交易量&#xff0c;从平台获得一定的返佣&…

【剑指Offer】28.对称的二叉树

题目 给定一棵二叉树&#xff0c;判断其是否是自身的镜像&#xff08;即&#xff1a;是否对称&#xff09; 例如&#xff1a;下面这棵二叉树是对称的 下面这棵二叉树不对称。 数据范围&#xff1a;节点数满足 0≤n≤1000&#xff0c;节点上的值满足 0∣val∣≤1000 要求&am…

sql注入(5), sqlmap工具

sql注入, sqlmap工具 请注意&#xff0c;在实际操作中使用sqlmap测试和利用SQL注入等安全漏洞应始终符合法律法规和道德准则&#xff0c;并且需要在拥有明确授权的情况下进行。在没有获得适当授权的情况下对任何系统或网络进行渗透测试都是非法的。 sqlmap是由python开发的测…

C++引用(起别名)

0.引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;从语法的角度来说编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。比如说你的名字和外号指的都是你本人。 void Test() {int a 10;int& ra …

【MAC】升级 Mac os 后报错

背景 17 年买的 mac&#xff0c;发现很多软件都无法安装&#xff0c;于是升级 mac os 到 10.13&#xff0c;从官网下载 10.13 版本&#xff0c;之后升级&#xff0c;升级还算顺利。但使用 git 的时候发现出现问题了。 问题 使用 git 出现如下错误 xcrun: error: invalid ac…

第二证券:市净率高好还是低好?

市净率是一个衡量公司股票投资价值的指标&#xff0c;通过比较公司股票价格和公司每股净资产的比值来评估公司股票的估值水平。市净率高好还是低好这个问题并没有一个简单的答案&#xff0c;取决于具体的市场环境和投资者的需求。本文将从多个角度分析市净率高好还是低好。 首…

头文件 <cstdarg> 的使用

进行函数可变参数的实现。 va_list&#xff1a; 适用于 va_start()、va_arg() 和 va_end() 这三个宏存储信息的类型。void va_start(va_list ap, last_arg)&#xff1a; 初始化 ap&#xff0c;其中 last_arg 是最后一个传递给函数的已知固定参数。type va_arg(va_list ap, typ…

How to install mysql 8.0 based on podman

创建配置目录 mkdir -p ~/data/podman/mysql-8.0/etc创建数据存储目录 mkdir -p ~/data/podman/mysql-8.0/var临时启动一个实例 docker run --detach \ --restart always \ --publish 23306:3306 \ --name mysql-8.0 \ --volume /usr/share/zoneinfo/Asia/Shanghai:/etc/lo…

安装运行vue-element-admin的报错问题-解决办法

文章目录 1.第一处2.第二处3.安装运行 在使用vue-element-admin时&#xff0c;使用命令安装&#xff1a; npm install -registryhttps://registry.npm.taobao.org会报错&#xff0c;不通过。需要修改两处。 1.第一处 在目录vue-element-admin-master\src\components\Markdown…

【监督学习】基于合取子句进化算法(CCEA)和析取范式进化算法(DNFEA)解决分类问题(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Docker SpringBoot项目连接本地数据库

要让本地的容器运行的应用程序连接到本机上的PostgreSQL数据库&#xff0c;可以使用以下步骤&#xff1a; 确保本机上已经安装并运行了PostgreSQL数据库。可以使用psql命令行工具或其他可视化工具来管理和连接到本机上的数据库。 在应用程序的配置文件中&#xff0c;将数据库连…

【工具】转码silk格式为mp3

【工具】转码slk格式为mp3 前提 安装 ffmpeg 【安装】Linux安装ffmpeg_linux安装ffmpeg4.4_我是Superman丶的博客-CSDN博客 GitHub - kn007/silk-v3-decoder: [Skype Silk Codec SDK]Decode silk v3 audio files (like wechat amr, aud files, qq slk files) and convert to o…

DataStructure--Tree

1.Tree–Basic 参考链接 2.Binary Tree 参考链接 二叉树是有序树。 简单地理解&#xff0c;满足以下两个条件的树就是二叉树&#xff1a; 1. 本身是有序树&#xff1b; 2. 树中包含的各个节点的度不能超过 2&#xff0c;即只能是 0、1 或者 2&#xff1b;2.1 满二叉树 如果…