在这个函数中,为什么我们需要用unsigned char进行转换?我们不能用char进行转换并得到相同的结果吗?因为两者的范围都是“255”?为什么选择unsigned char?
假设没有ASCII码等于-126。我可以说255也是一样的;两者都会给予你一个垃圾值。如果你告诉我我们选择它是因为我们正在处理字节,它的最大值是255,我会说我们只是在比较。所以,在s1和s2中,结果总是ASCII码。为什么我们选择无符号字符?
#include "libft.h"
int ft_strncmp(const char *s1, const char *s2, size_t n)
{
size_t i;
i = 0;
if (n == 0)
return (0);
while (i < n && (s1[i] != '\0' || s2[i] != '\0'))
{
if (s1[i] != s2[i])
return ((unsigned char)s1[i] - (unsigned char)s2[i]);
i++;
}
return (0);
}
字符串
3条答案
按热度按时间fd3cxomn1#
在这个函数中,为什么我们需要用unsigned char进行强制转换?
因为该函数复制了标准库函数
strncmp()
的行为,该函数比较参数的字节,就好像它们具有unsigned char
类型一样。我们不能用char进行强制转换并得到相同的结果吗?因为两者的范围都是“255”。
C语言规范明确允许
char
具有与unsigned char
或signed char
相同的范围和行为,后者非常常见。在signed char
等价的情况下(假设8位字节,这在C23之前没有保证),char
的范围是-128到127。您仍然可以使用
char
类型进行比较,但是在某些系统上会产生与其他系统不同的结果。(Also:元素已经是
char
s。在该类型中不需要强制转换来进行比较。)为什么选择unsigned char?
这是因为
unsigned char
可以产生所需的顺序,而char
可能不会,而且因为使用unsigned char
可以在不同的实现中产生一致的顺序,即使你想实现一个不同的顺序。假设没有ASCII码等于-126,我可以说255也是如此;两者都会给你一个给予垃圾值。
ASCII与此关系不大。C并不假定
char
值是特定的ASCII码。运行时字符集可能与ASCII不同或不兼容--比如说EBCDIC--今天使用的机器就是这种情况。这里没有假设或依赖任何特定的字符集。ljo96ir52#
标准C库执行 string 函数,就好像字符是
unsigned char
一样。对于本小节中的所有函数,每个字符都应该被解释为具有
unsigned char
类型(因此每个可能的对象表示都是有效的,并且具有不同的值)。由于
char
可能是 signed 或 unsigned,当char
之一为负时,减去2char
与2unsigned char
的结果不同。因此转换为unsigned char
形成了类似C库的差异。学究气
char
和int
的宽度是相同的,因此通过减法来返回具有正确符号的差值有溢出的风险。((unsigned char *)s1)[i]
可以与(unsigned char)s1[i]
不同,并且是首选格式。下面解决这两个问题:
字符串
或
型
vmpqdwk33#
在这种情况下,unsigned char的使用与字符比较的工作方式有关,特别是在处理ASCII范围之外的字符时。
在C标准中,像memcmp和strcmp这样的函数的行为是根据无符号字符值定义的。当你在比较之前将字符转换为无符号字符时,你要确保比较是在无符号上下文中完成的。当处理在有符号字符范围内具有负值的字符时,这一点很重要。
在您的特定示例中,转换为unsigned char用于处理当被视为有符号字符时可能具有负值的字符。这是相关的,因为标准允许字符在有符号字符表示中具有负值,并且直接将它们作为有符号字符进行比较可能不会产生正确的结果。
考虑char是有符号的,范围是-128到127。如果一个字符的值大于127(例如,255),那么当它存储在有符号的char中时,它将被视为负值。将它转换为unsigned char可以确保它在比较期间被视为正值。
通过在ft_strncmp函数中将s1[i]和s2[i]都转换为unsigned char,您明确声明比较应该在unsigned上下文中进行,避免与有符号char表示相关的问题。
因此,虽然您正确地认为ASCII范围是0到127,并且在某些上下文中可能会将127以上的值视为垃圾,但在字符比较函数中使用unsigned char是正确处理所有可能的字符值的良好实践,特别是在底层表示可能是有符号的情况下