空终止字符串的基本原理是什么?

2023-12-26

尽管我非常喜欢 C 和 C++,但我还是忍不住对空终止字符串的选择感到摸不着头脑:

  • 长度前缀(即 Pascal)字符串在 C 之前就已存在
  • 长度前缀字符串通过允许恒定时间长度查找使多种算法更快。
  • 带长度前缀的字符串更难以导致缓冲区溢出错误。
  • 即使在 32 位计算机上,如果允许字符串为可用内存大小,则长度前缀字符串仅比空终止字符串宽三个字节。在 16 位机器上,这是一个字节。在 64 位机器上,4GB 是合理的字符串长度限制,但即使您想将其扩展到机器字的大小,64 位机器通常也有足够的内存,使得额外的 7 个字节成为空参数。我知道最初的 C 标准是为极其糟糕的机器(就内存而言)编写的,但效率论点并不能让我信服。
  • 几乎所有其他语言(即 Perl、Pascal、Python、Java、C# 等)都使用长度前缀字符串。这些语言通常在字符串操作基准测试中击败 C,因为它们处理字符串的效率更高。
  • C++ 对此做了一些修正std::basic_string模板,但期望以 null 结尾的字符串的纯字符数组仍然普遍存在。这也是不完美的,因为它需要堆分配。
  • 以空结尾的字符串必须保留一个字符(即空),该字符不能存在于字符串中,而长度前缀的字符串可以包含嵌入的空值。

其中一些事情比 C 更晚才被发现,因此 C 不知道它们也是有道理的。然而,有几个早在 C 出现之前就已经很简单了。为什么选择以空结尾的字符串而不是明显优越的长度前缀?

EDIT: 既然有人要求facts(并且不喜欢我已经提供的那些)就我上面的效率点而言,它们源于以下几件事:

  • 使用空终止字符串进行连接需要 O(n + m) 时间复杂度。长度前缀通常只需要 O(m)。
  • 使用空终止字符串的长度需要 O(n) 时间复杂度。长度前缀是 O(1)。
  • 长度和连接是迄今为止最常见的字符串操作。在某些情况下,以 null 结尾的字符串可以更有效,但这种情况发生的频率要低得多。

从下面的答案来看,在某些情况下,空终止字符串效率更高:

  • 当您需要切断字符串的开头并将其传递给某些方法时。即使允许您销毁原始字符串,您也不能真正在恒定时间内使用长度前缀来完成此操作,因为长度前缀可能需要遵循对齐规则。
  • 在某些情况下,如果您只是逐个字符地循环字符串,您也许可以保存 CPU 寄存器。请注意,这只适用于您没有动态分配字符串的情况(因为这样您就必须释放它,从而需要使用您保存的 CPU 寄存器来保存最初从 malloc 和朋友那里获得的指针)。

以上都不像长度和连接那么常见。

下面的答案中还有一个断言:

  • 你需要剪掉绳子的末端

但这是不正确的——对于以 null 结尾的字符串和长度前缀的字符串来说,时间是相同的。 (空终止字符串只需在您想要新结尾的位置粘贴一个空值,长度前缀只需从前缀中减去。)


来自马嘴 https://www.bell-labs.com/usr/dmr/www/chist.html

BCPL、B 或 C 都不支持 字符数据强在 语言;每个都对字符串处理得很多 就像整数向量和 通过一些补充一般规则 惯例。在 BCPL 和 B a 中 字符串文字表示的地址 一个静态区域初始化为 字符串的字符,打包成 细胞。在 BCPL 中,第一个打包字节 包含的字符数 字符串; B 中没有计数 字符串以 a 结尾 特殊字符,B 拼写的*e。此更改已部分完成 以避免长度限制 由持有引起的字符串 计数 8 位或 9 位槽,以及 部分原因是维持计数 根据我们的经验,似乎较少 比使用终结器方便。

Dennis M Ritchie, Development of the C Language

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

空终止字符串的基本原理是什么? 的相关文章

随机推荐

  • 如何在React Native中离线捆绑iOS?

    任何人都可以解释一下如何从 反应本机 代码生成 iOS 应用程序的离线包吗 我已经尝试过了如何为react native生成 ipa文件 https stackoverflow com questions 41970435 how to g
  • 如何递归连接字符串元素列表

    我正在查看准备考试的示例 坦率地说 我不太擅长递归或列表 尤其是列表 给定一个节点类 它将保存字符串 不是通用的 编写一个名为 concat 的递归 java 函数 该函数采用表示链表头的节点 并返回表示链表中所有元素的串联的字符串 如果链
  • 对列表进行子集化 - plyr 方式?

    我经常拥有按一个或多个变量分组的数据 每组内有多个注册 从数据框中 我希望根据各种标准选择组 我通常使用 split sapply rbind 方法 其中使用逻辑向量从列表中提取元素 这是一个小例子 我从一个包含一个分组变量 组 的数据框开
  • 如何在 Jenkins (VS2012) 中运行发布/点击一次构建步骤

    我们有一个简单的 C 解决方案 VS 2012 它有一个发布步骤 单击一次向导 使用 ftp 我已经设置了一个 jenkins 构建项目来在 SVN 触发器上构建它 通过 MSBuild 我无法让它构建 通过 MSBuild 发布 单击一次
  • WPF 嵌套 Scrollviewers - 将控制权交还给父级 scollviewer

    这就是我的控制树的样子
  • Android P 预览上的 toast View 的 IllegalStateException

    在尝试发布我的应用程序进行生产时 预发布报告通知我 Pixel 2 Android P Preview 设备上出现错误 该错误与我的自定义 toast 消息有关 该消息表示视图 已添加到窗口管理器 java lang IllegalStat
  • 不用sudo重启nginx?

    所以我希望能够在不输入任何密码的情况下进行 cap deploy 我已经设置了所有私钥 这样我就可以很好地访问远程服务器 并且现在使用 svn over ssh 所以那里没有密码 我还有最后一个问题 我需要能够重新启动 nginx 现在我有
  • 导入 javax.validation.constraints.NotEmpty;不工作[重复]

    这个问题在这里已经有答案了 我目前有一个 java spring boot 应用程序 我将版本 在代码中 从 2 1 4 更改为 2 3 0 但结果我遇到了错误error package javax validation constrain
  • android服务导出属性?

    我对android平台还很陌生 我想导出我的服务以供公众使用 我在开发人员文档中找到了一些内容 android exported其他应用程序的组件是否可以调用该服务或与其交互 如果可以 则为 true 如果不能 则为 false 当值为 f
  • 为闪亮仪表板中的滑块添加不同的静态颜色

    我是闪亮的新手 我想为滑块提供静态颜色 无论闪亮仪表板中选择的范围如何 我想要滑块有不同的颜色 如下所示 例如 0 到 40 红色 40 到 60 蓝色 60 到 100 绿色 请帮我解决这个问题 我的代码 library shiny li
  • 为什么更喜欢模板方法而不是依赖注入?

    我一直在阅读 Gamma 等人写的 设计模式 我有一个关于模板方法与依赖注入相比的问题 使用模板方法 您可以使用为所需操作或计算提供替代方案的策略来 模板化 类 因此 您不需要从多种替代方案中选择一种策略并将该策略编码到类中 而是允许类的用
  • 使用 Launch4j VM 参数路径包装的 JavaFX 项目

    对于我的一些项目 我使用 JavaFX 作为 GUI 在 JavaFX 被拆分为 OpenJFX 之前 我没有遇到任何问题 现在我想使用最新版本的 JDK 和 JavaFX 因此必须进行一些更改 在 Eclipse 中工作时 一切都按预期运
  • 使用 main() 函数进行递归[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在编写一个程序来使用递归计算阶乘
  • 将图像上传到 codeigniter 中的 MySQL 数据库 blob

    我想将图像上传到mysql数据库以存储许多信息 我已附上 3 MVC 代码供您参考 请帮助我 ref http forum codeigniter com thread 1205 html http forum codeigniter co
  • 子进程返回码中的Python“return not”语句

    我刚刚在Python中遇到了一行非常奇怪的代码 self myReturnCode externalProcessPopen returncode return not self myReturnCode 究竟是什么return not代表
  • 当有新更新可用时,Angular 4 PWA Service Worker 不会更新

    在我更新 Angular 4 PWA 应用程序并部署后 用户无法获得新的更新 直到用户清除缓存并刷新浏览器 Sw不更新 即使我按下 crome Dev 中的更新按钮 它也不会更新 我必须清除缓存并刷新浏览器 我用过这些包 Angular s
  • Discord 机器人:修复“找不到 FFMPEG”

    我想让我的 Discord 机器人加入语音聊天 但每次我这样做时 我都会在 log cmd 中收到错误消息 FFMPEG not found 请帮我 错误图片 这是代码 client on message message gt Voice
  • pymysql无法连接mysql

    我正在尝试使用 pymsql 连接到 MySQL 数据库 主机是 115 28 236 225 并使用默认端口 3306 代码如下 db connect py import pymysql def connDB conn pymysql c
  • jQuery悬停不适用于动态元素

    我从数据库中获取数据 并根据匹配的数量 我想输出 div img src images account related icons link delete png div 我希望该图像在悬停时发生变化 所以我使用以下代码 link dele
  • 空终止字符串的基本原理是什么?

    尽管我非常喜欢 C 和 C 但我还是忍不住对空终止字符串的选择感到摸不着头脑 长度前缀 即 Pascal 字符串在 C 之前就已存在 长度前缀字符串通过允许恒定时间长度查找使多种算法更快 带长度前缀的字符串更难以导致缓冲区溢出错误 即使在