为什么 C 提供的整数类型对于基本上任何项目来说都不够好?

2024-03-06

我更像是一名系统管理员而不是程序员。但我确实花费了大量的时间研究程序员的代码,试图找出问题所在。以及数量令人不安的that当程序员期望 __u_ll_int32_t 或其他任何定义(是的,我知道这不是真的),但要么期望定义该类型的文件位于其他地方,要么(这更糟糕但值得庆幸的是,很少有)期望该定义的语义与实际情况不同。

据我了解,C 故意不为整数类型定义宽度(这是一件好事),而是为程序员提供了char, short, int, long, and long long,在他们所有签署和未签署的荣耀中,具有实现(希望)满足的定义的最低限度。此外,它为程序员提供了实现必须提供的各种宏,以告诉您 char 的宽度、最大的 unsigned long 等信息。然而,任何重要的 C 项目似乎要做的第一件事就是导入或发明另一组类型明确给出 8、16、32 和 64 位整数。这意味着作为系统管理员,我必须将这些定义文件放在程序员期望的位置(毕竟,这是我的工作),但并非所有这些定义的所有语义都是相同的(这个轮子已被重新发明了很多次),据我所知,没有非临时的方法可以满足所有用户的需求。 (我有时会制作一个,我知道每次我这样做都会让小狗哭泣。)

尝试显式定义数字的位宽(使用专门不想这样做的语言)会给程序员带来什么好处,从而值得所有这些配置管理头痛?为什么仅了解定义的最小值和平台提供的 MAX/MIN 宏不足以完成 C 程序员想要做的事情?为什么您想要采用一种主要优点是可以跨任意位平台移植的语言,然后将自己键入特定的位宽度?


当 C 或 C++ 程序员(以下以第二人称)选择整型变量的大小时,通常会遇到以下情况之一:

  • You know (at least roughly) the valid range for the variable, based on the real-world value it represents. For example,
    • numPassengersOnPlane航空公司预订系统中应容纳largest http://planes.findthebest.com/l/242/Airbus-A380-800支持飞机,因此至少需要 10 位。 (向上舍入为 16。)
    • numPeopleInState在美国人口普查制表程序中需要适应人口最多的州 http://en.wikipedia.org/wiki/California(目前约为3800万),因此至少需要26位。 (向上舍入为 32。)

在这种情况下,您需要以下语义int_leastN_t from <stdint.h>。程序员通常使用精确宽度intN_t在这里,从技术上讲他们不应该这样做;然而,8/16/32/64 位机器如今占据绝对主导地位,以至于这种区别仅仅是学术上的。

You could使用标准类型并依赖诸如“int必须至少为 16 位”,但这样做的缺点是没有标准maximum整数类型的大小。如果int当您实际上只需要 16 位时,恰好是 32 位,那么您就不必要地将数据大小增加了一倍。在许多情况下(见下文),这不是问题,但如果您有一个数组millions的数字,那么你会得到很多页面错误。

  • 您的数字不需要那么大,但出于效率原因,您需要一种快速的“本机”数据类型,而不是可能需要在位掩码或零/符号扩展上浪费时间的小数据类型。

这是int_fastN_t输入<stdint.h>。然而,通常只使用内置的int这里,在 16/32 位时代的语义是int_fast16_t。它不是 64 位系统上的本机类型,但通常足够好。

  • 该变量是内存量、数组索引或强制转换指针,因此需要一个取决于可寻址内存量的大小。

这对应于 typedefsize_t, ptrdiff_t, intptr_t等你have在这里使用 typedefs 因为有no保证内存大小的内置类型。

  • 该变量是使用以下命令序列化到文件的结构的一部分fread/fwrite,或从具有自己的固定宽度数据类型的非 C 语言(Java、COBOL 等)调用。

在这些情况下,您确实需要精确宽度的类型。

  • 您只是没有考虑合适的类型,并使用int出于习惯。

通常,这种方法效果很好。


所以,总而言之,所有的 typedef 都来自<stdint.h>有他们的用例。然而,内置类型的用途受到限制,原因如下:

  • Lack of maximum这些类型的尺寸。
  • 缺乏原生 memsize 类型。
  • 64 位系统上的 LP64(在类 Unix 系统上)和 LLP64(在 Windows 上)数据模型之间任意选择。

至于为什么会有这样的many固定宽度的冗余 typedef (WORD, DWORD, __int64, gint64, FINT64等)和memsize(INT_PTR, LPARAM, VPTRDIFF等)整数类型,主要是因为<stdint.h>C 的发展较晚,人们仍在使用不支持它的旧编译器,因此库需要定义自己的编译器。 C++ 有这么多字符串类的原因也是如此。

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

为什么 C 提供的整数类型对于基本上任何项目来说都不够好? 的相关文章

随机推荐

  • 如何将 Qt5 和 Qt Creator 2.6.1 与 VS 2012 的编译器一起使用?

    官方下载 http qt project org downloads现在仅包含 VS 2010 的 Qt 库 5 0 0 我在 VS 2012 Express 中尝试了它们 但收到一条错误消息 错误 LNK2038 检测到 MSC VER
  • 有没有办法在所有 jquery 脚本运行后查看网页的源代码?

    我目前使用 Chrome Firefox 进行 Web 开发 有没有一个插件 或者我只是另一种方式 您可以在所有 jQuery 插件运行后查看 HTML 源代码 我只是想看看 jQuery 修改了什么以及如何修改 HTML Firebug
  • 带有 gcc stdlib 的 icpc C++11

    我正在使用 icpc 非可选 并且使用 std c 0x 进行编译 因此我可以使用ambas 然而 当我这样做时 它会使用 gcc stdlib 创建 havok 其中一个支持另一个不支持的功能 我尝试过定义 GXX EXPERIMENTA
  • 使用指定存储库中的 Git 分支动态填充 Jenkins Choice 参数

    我有一个参数化的 Jenkins 作业 它需要输入特定 Git 存储库中的特定 Git 分支 目前该参数是一个字符串参数 有没有办法让这个参数成为选择参数并用Git分支动态填充下拉列表 我不想要求有人在每次创建新分支时手动配置下拉列表来维护
  • php-fpm 进程监控/分析

    我最近遇到了 php fpm 进程使用 如活动进程数量 的问题 达到了最大可用进程的峰值 并停止执行其他脚本 直到有问题的进程完成 更详细一点 我当前的 php fpm 设置是 pm static pm max children 100 我
  • 在 Java 中以编程方式清除控制台

    我创建了一个示例 Java 应用程序 我想清除窗口选项 即 Register Login Clear 如果用户按 3 我需要以编程方式清除所有选项 就像是Console clear 有什么办法可以用 Java 做到这一点吗 您将需要输出一堆
  • 如何将较小的位图复制到较大的位图?

    希望这应该是一个简单的问题 我正在尝试将一系列小位图复制到较大的位图中 将它们并排排列 像素中没有任何间隙或重叠 例如 如果我有 3 个正方形位图 我想将它们复制到一个细长的矩形中 我知道如何做相反的事情 即从较大的位图创建一个小位图 但不
  • 与应用内购买的“无法连接到 iTunes”相关的供应商 ID 错误消息是什么?

    这是一条神秘的错误消息 LaunchServices 无法获取供应商ID 我猜这是某个苹果服务器现在宕机了 很快就会恢复在线 背景 我的 iOS 应用程序之前没有批准的应用内购买 因此这仍然是必须提交新版本应用程序以及新的应用内购买产品的阶
  • Angular 5 无法找到“object”类型的不同支持对象“[object Object]”。 NgFor 仅支持绑定到 Iterables,例如数组

    我正在尝试从我的后端 api 返回产品并将其显示在我的前端页面上 当我执行 ngFor 循环时 它给了我一个错误 这是我的代码 我的后端API data 0 name perferendis totalPrice 323 76 rating
  • Rails 设计:after_confirmation

    有没有办法创建一个after confirmation do something 目标是在用户确认使用 Devise 后发送电子邮件 confirmable 我正在使用 Devise 3 1 2 它有一个占位符方法after confirm
  • 如何使用stdext::hash_map?

    我想看一个如何正确重写 stdext hash compare 的简单示例 以便为我自己的用户定义类型定义新的哈希函数和比较运算符 我正在使用 Visual C 2008 这就是你可以做到的 class MyClass Hasher con
  • Vue Axios 动态 URL

    我想在 vue js 应用程序中动态创建 axios post 操作的 URL 路径 这是动作 editProduct function dispatch commit payload axios put http localhost 80
  • 如何删除单个链表中的循环?

    我不确定在不使用 O N 内存和标志的情况下如何找到循环的开始 找到循环内部的一个节点 具体参见1800 INFORMATION的回答 我们称这个节点为C 通过将指针从 C 前进直到再次到达 C 来求出循环的长度 循环的长度是它所采取的步数
  • 如何在方案中编写程序来查找数字列表的因数

    这是单个整数的代码 它如何扩展到函数列表 define factors n define factors d cond gt d n list modulo n d 0 cons d factors d 1 else factors d 1
  • Java日历的setMonth方法工作错误吗?

    我有如下的小代码 我预计结果应该是7 但它打印了6 如果我取消注释该行tmp get Calendar MONTH 它运行正常 打印7 请告诉我原因 我在 MacOS 中使用 JDK 1 7 0 25 public static void
  • 安装 scrapy 清理失败

    我一直在努力得到Scrapy使用 pip 安装 以便抓取 NBA 赛季的赛程表和得分 在过去的 6 个小时里 我一直在努力尝试安装它 我已经逐字按照设置说明进行操作 但仍然无法使其正常工作 任何帮助将不胜感激 终端窗口输出如下 非常感谢 顺
  • Keycloak 重定向 URI 正在将端口 0 添加到 url

    在keycloak 中遇到redirect uri 错误 发现 JIRA 记录了相同的问题KEYCLOAK 7237 https issues jboss org browse KEYCLOAK 7237 只是想检查一下是否有解决办法 有人
  • AngularJS:是否可以使控制器中的特定表单输入字段无效?

    我有一个地址文本输入字段 每当输入地址并单击输入字段旁边的搜索按钮时 我都会对地址进行地理编码 并将输入文本替换为地理编码器的结果 我还设置了一个范围变量 addressOk 是否可以根据以下内容使该特定表单输入字段无效 scope add
  • 将原始 JSON 加载到 Pig 中

    我有一个文件 其中每一行都是一个 JSON 对象 实际上 它是 stackoverflow 的转储 我想尽可能轻松地将其加载到 Apache Pig 中 但我无法弄清楚如何告诉 Pig 输入格式是什么 这是一个条目的示例 id oid 50
  • 为什么 C 提供的整数类型对于基本上任何项目来说都不够好?

    我更像是一名系统管理员而不是程序员 但我确实花费了大量的时间研究程序员的代码 试图找出问题所在 以及数量令人不安的that当程序员期望 u ll int32 t 或其他任何定义 是的 我知道这不是真的 但要么期望定义该类型的文件位于其他地方