【问题标题】:What is the difference between char and unsigned char in this situation?在这种情况下 char 和 unsigned char 有什么区别?
【发布时间】:2022-01-03 23:11:45
【问题描述】:

这是memchr 函数的简单克隆;问题是它适用于char 以及unsigned char

我的问题是为什么那个人说应该是unsigned char

void    *ft_memchr(const void *s, int c, size_t n)
{
    size_t          i;
    unsigned char   *src;

    src = (unsigned char *)s;
    i = 0;
    while (i < n)
    {
        if (src[i] == (unsigned char)c)
            return (src + i);
        i++;
    }
    return (0);
}

那个代码和这个有什么区别:

void    *ft_memchr(const void *s, int c, size_t n)
{
    size_t          i;
    char    *src;

    src = (char *)s;
    i = 0;
    while (i < n)
    {
        if (src[i] == (char)c)
            return (src + i);
        i++;
    }
    return (0);
}

【问题讨论】:

  • 请注意,对于几乎所有情况,小于int 的任何类型的值都将为promotedint。此促销(例如src[i] == (char)c)也将进行签名扩展。在将 char 值与实际 int 值进行比较时,这可能会导致问题。
  • 在符号幅度系统上使用有符号字符会混淆负零和正零。
  • 它们可能相同也可能不同,但使用signed charft_memchr 版本可能会有所不同。
  • 感谢您的回答,但您能否提供一个示例,说明使用 char 会导致我们出现问题?

标签: c char unsigned


【解决方案1】:

当您使用unsigned char 时,行为完全由 C 标准定义:

  • C 2018 6.2.6.1 3 说unsigned char 对象应用纯二进制表示。脚注清楚地表明 unsigned char 的所有位都参与其中,因此它没有填充位。
  • C 2018 6.2.6.1 4 保证我们可以使用 unsigned char 处理表示任何对象的字节。
  • C 2018 6.2.6.1 1 和 2 允许 unsigned char 以外的整数类型具有填充位。

出于实际目的,现代 C 实现在很大程度上消除了 charsigned char 类型中留下的缺点。但是,理论上,它们可以具有填充位(并且作为char 访问的内存中的所有位可能对其值没有贡献,因此将相同的char 值写入另一个内存位置可能不会重现所有位)并且它们可以有多种表示(位模式)来表示相同的值(零的两种表示,一种带有正号位,一种带有负号位)。 (整数类型通常也可以有陷阱表示,但 C 2018 6.2.6.1 5 不允许这些对字符类型产生影响。) C 2018 6.2.6.2 3 表示存储时不一定保留“负零”在一个物体中;它可能会变成“正常的零”。

因此,理论上,当src[i]char 时,它的值可能等于c,即使src[i] 的内存中的位与c 的位不同,因此memchr 例程将返回不正确的结果。

您在实践中不太可能遇到这样的 C 实现,但最终结果是 C 标准保证 unsigned char 的行为而不是 char 的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-03
    • 2020-10-08
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    • 2020-06-26
    相关资源
    最近更新 更多