【问题标题】:How to do safe arithmetic on the char type如何对 char 类型进行安全算术运算
【发布时间】:2018-01-04 13:51:10
【问题描述】:

在纯 C 中,char 类型是至少 8 位宽的类型,具有实现定义的符号。

正如When to use the plain char type in C 问题的答案所暗示的,当您的数据类型有意为字符串并且行为类似于普通C 字符串时,应使用此类型,例如允许使用标准库中的string.h 函数.

但是,在某些情况下,您可能需要对这些值进行算术运算。例如 UTF-8 数据,您必须自己编写某种类型的处理器或显示例程(您的目标上没有合适的库解决方案)。

如何以最安全、最便携的方式处理这种情况?

【问题讨论】:

  • 明确声明签名? signed charunsigned char 具有完全指定的行为。您仍然可以使用普通的char,只需在将其用于算术目的之前转换为char 的适当签名版本(重要:您需要两步转换,到char 的适当签名,然后到适当的必要时调整大小的类型;当 char 碰巧被签名并且设置了高位时,(unsigned)mychar 将行为不端,除非您这样做 (unsigned)(unsigned char)mychar)。
  • @ShadowRanger 我目前的想法大致是:在需要处理此类的例程中,通常具有指向 char 输入的指针,将单个值转换为 unsigned charsigned char 以适合任何算术。
  • 算术时"Usual Arithmetic Conversions" 适用。
  • 不,如果您坚持将char 类型仅用于字符数据的做法,那么您永远不需要对该类型的值执行算术运算。字符不是数字,因此对它们的算术定义不明确。字符在计算机内存中表示为数字意味着您在技术上可以对它们执行算术运算,但这样做时您不再将它们视为字符。如果你想执行算术,你应该通过适当的机制(可能只是赋值或强制转换)转换为任何其他数字类型。
  • @JohnBollinger:“所以对它们的算术定义不明确”我反对。 “您应该转换为任何其他数字类型” 为什么? C 隐含地做到了这一点。请看我之前的评论。

标签: c string char


【解决方案1】:

对字符值进行操作的一种非常安全的方法可能是使用 unsigned char 类型并在表达式中立即将它们转换为 unsigned(例如,写成 (unsigned) a - (unsigned) b 而不是 a-b)。

如果你在算术表达式中使用字符类型,即使是unsigned char,它也会被提升为int1,并且在C中没有完全指定int值的算术(值得注意的是,溢出时的行为是未定义的)。立即将每个对象强制转换为 unsigned 将有效地回避这一点,从而对无符号值进行算术运算,从而得到更完整的定义。

这不是一个完美的解决方案。这将导致繁琐的代码,有大量的(unsigned) 强制转换。而且,当然,定义了行为并不意味着你总是会得到想要的行为——人们仍然可以在不需要的时候编写换行(而不是溢出)的表达式。没有办法消除所有人为错误。

脚注

1 根据其他地方的讨论,在深奥的 C 实现中,charint 的大小可能相同,在这种情况下,unsigned char 将被提升为 @987654334 @。出于所有实际目的,您可以忽略这一点。

【讨论】:

  • 您为什么坚持使用无符号算术还不是很清楚。好老的int怎么了? Unsigned 是一般用于算术的 PITA。无符号位摆弄更好,但算术摆弄和位摆弄是两个完全不同的东西。
  • “在深奥的 C 实现中,charint 的大小可能相同” - 是的。例如。 C40 信号处理器和 C:由于 TMS320C3x/C4x 字符是 32 位(使其可单独寻址),因此一个字节也是 32 位。这会产生您可能意想不到的结果;例如,sizeof (int) == 1(不是 4)。 TMS320C3x/C4x 字节和字是等效的(32 位)。(复制自MS320C3x/C4x Optimizing C Compiler User’s Guide
  • @n.m.:int 的问题是 int 算术没有完全指定,正如答案所述。
  • @EricPostpischil“int 算术没有完全指定”所以?它的规定足以满足大多数字符处理需求。完全指定是一个很好的属性,但有用仍然是必要的。
猜你喜欢
  • 2020-10-11
  • 2012-08-14
  • 2021-05-03
  • 2023-01-11
  • 2013-02-06
  • 1970-01-01
  • 2023-03-29
  • 2014-10-02
  • 1970-01-01
相关资源
最近更新 更多