姬世鹏 发表于 2019-11-14 13:54:17

关于两个无符号整形相减结果能否为负

#include <stdio.h>
#include <string.h>

int main()
{
      char str1[] = "love";
      char str2[] = "FishC";

      if (strlen(str1) - strlen(str2) < 0)
      {
                printf("字符串%s比字符串%s短!\n", str1, str2);
      }
      else
      {
                printf("字符串%s比字符串%s长!\n", str1, str2);
      }

      return 0;
}//此时输出结果为strlen(str1) - strlen(str2) > 0,输出else语句,但将strlen(str1) - strlen(str2)单列出来时有如下情况

#include <stdio.h>
#include <string.h>

int main()
{
      char str1[] = "love";
      char str2[] = "FishC";

      printf("%d",strlen(str1) - strlen(str2) );
}//此时运行结果为-1,不明白为什么两个的结果会相反。

EushullyChan 发表于 2019-11-14 13:54:18

姬世鹏 发表于 2019-11-14 21:40
#include
#include



首先你要搞清楚,不论是有符号还是无符号数相加减,cpu都是用其补码做加法运算(cpu只有加法器)。4-5就是4+(-5),4的补码是0x00000004,-5的补码是0xFFFFFFFB,这个数相加等于0xFFFFFFFF。于是呢,打印%d就是把0xFFFFFFFF当作带符号数进行打印,相当于-2^31+2^30+2^5+...2^0=-1。同理打印%u时当作无符号则:2^31+2^30+2^5+...2^0=4294967295。
以上,我觉得说到这里应该都能看懂了,如果还没看懂得话,建议好好复习一下小甲鱼的教程。

EushullyChan 发表于 2019-11-14 16:08:09

strlen确实返回的是无符号数,既然你知道这一点,就不该用它做减法来比较大小,这样你大于0的条件就是恒成立了的。至于你为何会得到负数……你用%d打印出来的是带符号的,FFFFFFFF(假设是x86)算上符号位就是-1

micolar 发表于 2019-11-14 21:25:46

printf("%u",strlen(str1) - strlen(str2) );

printf("%d",(int)(strlen(str1) - strlen(str2)));

姬世鹏 发表于 2019-11-14 21:39:56

EushullyChan 发表于 2019-11-14 16:08
strlen确实返回的是无符号数,既然你知道这一点,就不该用它做减法来比较大小,这样你大于0的条件就是恒成 ...

#include <stdio.h>
#include <string.h>

int main()
{
      char str1[] = "love";
      char str2[] = "FishC";


      printf("%u",strlen(str1) - strlen(str2) );
}//此时结果虽然为正数,但结果很大,为什么会这样?

姬世鹏 发表于 2019-11-14 21:40:27

micolar 发表于 2019-11-14 21:25
printf("%u",strlen(str1) - strlen(str2) );

printf("%d",(int)(strlen(str1) - strlen(str2)));

#include <stdio.h>
#include <string.h>

int main()
{
      char str1[] = "love";
      char str2[] = "FishC";


      printf("%u",strlen(str1) - strlen(str2) );
}//此时结果虽然为正数,但结果很大,为什么会这样?
页: [1]
查看完整版本: 关于两个无符号整形相减结果能否为负