c# 为什么要使用unsigned char?

yb3bgrhw  于 2023-10-14  发布在  C#
关注(0)|答案(2)|浏览(334)

我在两个不同的代码中看到了返回部分使用的unsigned char。为什么要这样使用unsigned char?

int ft_strncmp(const char *s1, const char *s2, size_t n)
{
    size_t i;

    i = 0;
    if (!n)
        return (0);
    while ((s1[i] == s2[i]) && s1[i] && s2[i] && i < n)
        i++;
    return (s1[i] - s2[i]);
}

而这

int ft_strncmp(const char *s1, const char *s2, size_t n)
{
    size_t i;

    i = 0;
    if (!n)
        return (0);
    while ((s1[i] == s2[i]) && s1[i] && s2[i] && i < n)
        i++;
    return (*(unsigned char *)s1[i] - *(unsigned char *)s2[i]);
}

我相信它与Unicode字符有关,但我有一个问题。例如,当使用一个不在标准ASCII表中的字符(例如,'i','o')时,当我用char数据类型解释它时,它不会保持不变吗?在这种情况下,在返回部分使用unsigned char是什么意思?

qcbq4gxm

qcbq4gxm1#

如果char为8位,则如果MS位被设置,则其变为负数。如果你想比较字符代码>= 128,那么你会得到意想不到的效果。
例如,代码是128(无符号),那么作为有符号字符,它将是-128。
如果你从128中继承127,你会得到1,但是作为unsigned char,你会得到-128
这就是作者使用unsigned chars的原因。但他并没有做他认为正在做的事情。他的代码调用了未定义的行为。
它应该是:

return (unsigned char)s1[i] - (unsigned char )s2[i];
iszxjhcz

iszxjhcz2#

ft_strncmp例程似乎是为了模拟标准strncmp例程,尽管它有几个错误。C标准在C 2018 7.24.1 3中对它的字符串处理例程这样说:
对于本小节中的所有函数,每个字符都应该被解释为具有unsigned char类型(因此每个可能的对象表示都是有效的,并且具有不同的值)。
因此,为了符合C标准,即使例程被声明为具有const char *类型的参数,它也必须将它们指向的数据解释为unsigned char的元素。
strncmp的字符串参数被声明为const char *,尽管由于历史原因,数据被解释为unsigned char,涉及C语言的发展以及它是由不同的人在不同的时间实验性地增长的,而不是计划的。
如果您不是在编写一个例程来模拟C标准库例程或与它们进行交互,那么您并不总是需要使用unsigned char。拥有自己的字符串处理例程,将字符视为charsigned char(如果适合您的需要),这是完全合理的。
例如,当使用一个不在标准ASCII表中的字符(例如,'i','o')时,当我用char数据类型解释它时,它不会保持不变吗?
C标准要求 * 基本字符集 * 中的字符具有非负值(当存储在char中时,C 2018 6.2.5 3)。基本的执行字符集包括拉丁字母(以和表示)、十进制数字、29个图形字符:

! " # % & ’ ( ) * + , - . / : ;  ? [ \ ] ^ _ { | } ~

空格以及用于水平制表符、垂直制表符、换页符、警告、退格键、回车和新行控制字符。
其他字符允许有负值,在这种情况下,将它们的位解释为unsigned char会产生不同的值。因此,在编写处理字符的代码时,您可能需要对charunsigned char之间的潜在差异保持敏感。

相关问题