strcmp函数为什么要强制转换为unsigned char ?

横云断岭
博客专家认证
2010-09-13 11:07:16

下面是MS的代码


int __cdecl strcmp (const char *src, const char *dst)
{
int ret = 0 ;
while(!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
{
++src;
++dst;
}
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
}
...全文
701 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
某某9 2010-09-18
  • 打赏
  • 举报
回复
会涉及到整型提升。要避免符号位扩展,所以要转化为unsigned类型
xhjyhappy 2010-09-18
  • 打赏
  • 举报
回复
学习了~
renzhewh 2010-09-18
  • 打赏
  • 举报
回复
ls 有看过 《程序设计实践》的没,建议看看
renzhewh 2010-09-18
  • 打赏
  • 举报
回复

这个问题刚回答过

strcmp这样做,是为了可移植性,因为无法确定char 是有符号还是无符号;

对于数值为0、-128的两个字符来说,如果类型为有符号,那么比较的结果为大于,
但是当类型为无符号时,则判断二者小于。

为了避免这种同样的两个字符比较,产生的结果却不同的情况,需要将char 类型
强制转为unsigned char。

这个问题是由unsigned char 与 signed char的取值范围不同造成的
unsigned char 0 -- 255 ,因此 -128被认为是 128
signed char -128 -- 127 ,因此 128 被认为是-128

注:对于二者的交集 0 -- 127 范围内的字符比较,无需转换


oyster2008 2010-09-18
  • 打赏
  • 举报
回复
其实道理比较简单,字符串比较本来就是比较ASCII码大小,按照这个规则,ASCII码为254肯定大于ASCII码是1的字符,但是如果将字符当成带符号数的话,前者是-2,后者是1,想减结果是-3,也就是说前者更小,这肯定不符合字符串比较的原则
横云断岭 2010-09-18
  • 打赏
  • 举报
回复
我觉得还没有人说到点子上。

jim_king_2000,
无符号数的减法运算能保证只要数字每位一样,那么相减必定为0。反之也成立。
而带符号数无法保证这一点。也就是说,当相减为0时,两数的每一位不一定相等。

下面的测试程序,说明这个说法是不对的。



for (int i = -128; i<128; ++i)
{
for (int j = -128; j<128; ++j)
{
signed char a = i;
signed char b = j;
if ( (a == b) != ( (unsigned char)a == (unsigned char)b ) )
{
cout<<"i = "<<i;
cout<<"j = "<<j;
cout<<endl;
}

int tempInt1;
tempInt1 = a - b;
int tempInt2;
tempInt2 = (unsigned char)a - (unsigned char)b;

//if ( tempInt1 == 0 )
//{
// cout<<"i = "<<i;
// cout<<"j = "<<j;
// cout<<endl;
//}
if (tempInt1 != tempInt2)
{
cout<<"i = "<<i<<"j = "<<j;
cout<<" int1 = "<<tempInt1<<" int2 = "<<tempInt2;
cout<<endl;
system("pause");
}

}
}

十八道胡同 2010-09-17
  • 打赏
  • 举报
回复
无符号数的减法运算能保证只要数字每位一样,那么相减必定为0。反之也成立。
而带符号数无法保证这一点。也就是说,当相减为0时,两数的每一位不一定相等。


果然是的。。好好想想
hai040 2010-09-13
  • 打赏
  • 举报
回复
试了下,a-b=128
vc9
*(unsigned char*)&a - *(unsigned char*)&b=-128
...
乐CC 2010-09-13
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 jim_king_2000 的回复:]
这是C/C++语言的一个dark corner。
无符号数的减法运算能保证只要数字每位一样,那么相减必定为0。反之也成立。
而带符号数无法保证这一点。也就是说,当相减为0时,两数的每一位不一定相等。

LZ可以试试下面的代码:

C/C++ code

signed char a = 0;
signed char b = -128;
signed char c = a - b;……
[/Quote]
不好意思,3楼已经说明白了,刚没注意.
乐CC 2010-09-13
  • 打赏
  • 举报
回复
char 类型值有可能大于128,这样保证ret符号正确,楼主看下这句:

char i = 130;
char b = 100;
printf("%3d\n",i-b);

输出是负数的,如果改成:

printf("%3d\n",(unsigned char)i-(unsigned char)b);

结果的符号就是正确的,所以对char类型的判断,一定要转换unsigned保证不溢出.
pengzhixi 2010-09-13
  • 打赏
  • 举报
回复
好了 可以结贴了
Jim_King_2000 2010-09-13
  • 打赏
  • 举报
回复
这是C/C++语言的一个dark corner。
无符号数的减法运算能保证只要数字每位一样,那么相减必定为0。反之也成立。
而带符号数无法保证这一点。也就是说,当相减为0时,两数的每一位不一定相等。

LZ可以试试下面的代码:

signed char a = 0;
signed char b = -128;
signed char c = a - b;

运行程序可知,c为0。但是很显然,a与b并不相等。更要命的是,标准未规定char到底是signed的还是unsigned的。所以,要判断两个变量是否每个bit都相等,必须转换为无符号整数。
wyfwx 2010-09-13
  • 打赏
  • 举报
回复
无符号数减法运算的大小判断简单
hai040 2010-09-13
  • 打赏
  • 举报
回复
好像除了让dst>=0(这样不用判断*src)外没什么用
Rainqin123 2010-09-13
  • 打赏
  • 举报
回复
jim_king_2000不错,看好你这股,
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 jim_king_2000 的回复:]
这是C/C++语言的一个dark corner。
无符号数的减法运算能保证只要数字每位一样,那么相减必定为0。反之也成立。
而带符号数无法保证这一点。也就是说,当相减为0时,两数的每一位不一定相等。

LZ可以试试下面的代码:

C/C++ code

signed char a = 0;
signed char b = -128;
signed char c = a - b;……
[/Quote] 结果是-128
hust_zhangxiaowei 2010-09-13
  • 打赏
  • 举报
回复
会涉及到整型提升。要避免符号位扩展,所以要转化为unsigned类型
Jim_King_2000 2010-09-13
  • 打赏
  • 举报
回复
printf("%3d\n",i-b);
不可以这样做。因为这样的话,编译器会把i-b变成整型。

一定要这样写:
signed char c = a - b;
然后用调试器看。
honghu069 2010-09-13
  • 打赏
  • 举报
回复
char 大部分编译器默认是signed的,这样i 就是-2了,结果为负的也是正常的
[Quote=引用 5 楼 void_wuyu 的回复:]
char 类型值有可能大于128,这样保证ret符号正确,楼主看下这句:

C/C++ code

char i = 130;
char b = 100;
printf("%3d\n",i-b);


输出是负数的,如果改成:

C/C++ code

printf("%3d\n",(unsigned char)i-(unsigned char)b);


结果的符……
[/Quote]
honghu069 2010-09-13
  • 打赏
  • 举报
回复
vc6.0里 c=-128,应该没有一种编译器是0吧
[Quote=引用 3 楼 jim_king_2000 的回复:]
这是C/C++语言的一个dark corner。
无符号数的减法运算能保证只要数字每位一样,那么相减必定为0。反之也成立。
而带符号数无法保证这一点。也就是说,当相减为0时,两数的每一位不一定相等。

LZ可以试试下面的代码:

C/C++ code

signed char a = 0;
signed char b = -128;
signed char c = a - b;……
[/Quote]

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧