鱼C论坛

 找回密码
 立即注册
查看: 1461|回复: 4

[已解决]C语言

[复制链接]
发表于 2023-10-18 10:21:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
给一个声明为无符号类型的短整型变量赋值一个负数,为何打印的是65535
最佳答案
2023-10-18 10:22:23
这是因为无符号类型的短整型变量在内存中存储的是一个非负数。当你给一个无符号类型的短整型变量赋值一个负数时,发生了溢出现象。

无符号类型的短整型变量通常占用2个字节(16位),其取值范围为0到65535。当你给这个变量赋值一个负数时,负数会被转换为一个对应的正数。具体的转换规则是将负数的绝对值与2的n次方相减,其中n为该类型的位数。在这种情况下,负数的绝对值是32768,而2的16次方是65536,所以最终的结果是65536 - 32768 = 32768。

因此,当你打印这个无符号类型的短整型变量时,它的值是32768,即打印的是65535的补码形式。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-10-18 10:22:23 | 显示全部楼层
在C语言中,无符号类型的短整型变量(unsigned short)的取值范围是0到65535。当你试图给这种类型的变量赋值一个负数时,会发生所谓的\"下溢\"现象。

这是因为无符号类型的变量不会存储负数。当你试图给它赋值一个负数时,它会将这个数转换为一个正数。这个转换是通过将负数加上无符号类型的最大值(在这种情况下是65536)然后再加1来完成的。所以,如果你试图给一个无符号短整型变量赋值-1,它会被转换为65535。

这就是为什么当你给一个声明为无符号类型的短整型变量赋值一个负数时,打印的结果是65535。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-18 10:22:23 | 显示全部楼层    本楼为最佳答案   
这是因为无符号类型的短整型变量在内存中存储的是一个非负数。当你给一个无符号类型的短整型变量赋值一个负数时,发生了溢出现象。

无符号类型的短整型变量通常占用2个字节(16位),其取值范围为0到65535。当你给这个变量赋值一个负数时,负数会被转换为一个对应的正数。具体的转换规则是将负数的绝对值与2的n次方相减,其中n为该类型的位数。在这种情况下,负数的绝对值是32768,而2的16次方是65536,所以最终的结果是65536 - 32768 = 32768。

因此,当你打印这个无符号类型的短整型变量时,它的值是32768,即打印的是65535的补码形式。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-18 10:23:36 | 显示全部楼层
问题回答:

在C语言中,当一个无符号短整型变量被赋值一个负数时,发生了以下情况:

1. 如果该负数的绝对值小于或等于无符号短整型变量的最大值,那么该负数会被转换为无符号类型。
2. 如果该负数的绝对值大于无符号短整型变量的最大值,则发生了"unsigned integer overflow"(无符号整数溢出)。

对于无符号短整型变量(unsigned short int),其取值范围通常是0到65535,因此,当一个负数被赋给无符号短整型变量时,发生了无符号整数溢出。

具体来说,如果你给一个声明为无符号类型的短整型变量赋值一个负数,比如 -1,它会被转换为一个较大的正数,即 2^16 - 1,也就是 65535

下面是一个示例代码,展示了这个情况:
#include <stdio.h>int main() {    unsigned short int num;    num = -1;    printf("%hu\n", num);    return 0;}
输出结果为:
[/code]
65535
[/code]

希望能解答您的疑惑,如果还有其他问题,请随时提问。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-18 11:01:23 | 显示全部楼层
本帖最后由 AFUL 于 2023-10-18 12:06 编辑

首先,纠正一点:
unsigned short n = -1; // 输出是65535;
unsigned short n = -2; // 输出是65534;

然后,我再详细说明一下,这儿同时参考short类型。我们用0000,0000,0000,0000(16个0表示16位都是0)。
那么,
0000,0000,0000,0000这个二进制在short类型和unsigned short类型中都表示0,
同理,
0000,0000,0000,0001这个二进制在short类型和unsigned short类型中都表示1,
以此类推,
0111,1111,1111,1111这个二进制在short类型和unsigned short类型中都表示32767。
但是,
第一位是0在short类型中表示非负数,在unsigned short类型中一直是非负数,所以下一个二进制,
1000,0000,0000,0000这个二进制在short类型中表示-32768和unsigned short类型中都表示32768,
进而,
1000,0000,0000,0001这个二进制在short类型中表示-32767,在unsigned short类型中都表示32769,
以此类推,
1111,1111,1111,1111这个二进制在short类型中表示-1=-32768+32767,在unsigned short类型中都表示65535。(这个就是为什么赋值-1最后会显示65535)

实际上,更进一步,如果赋值65536,最后会显示0,
这是因为65536的二进制就是
1,0000,0000,0000,0000,而short这种类型只选择后面16位,所以最后short和unsigned short类型都显示0。
以此类推,
1,0000,0000,0000,0001,就是65537,最后short和unsigned short类型都显示1。
#include <stdio.h>
#include <stdlib.h>

int main() {
  // 0b数字,表示数字是二进制
        char s[32] = {0};
  int a = 0b00000000000000000000000000000000; // int类型32位, 最高位是符号位
  sprintf(s, "%b", a);
        printf("二进制: %s\n", s);
  short b =               0b0000000000000000;  // short类型16位, 最高位是符号位
  unsigned short c = b;  // unsigned short类型16位, 最高位不是符号位
  printf("int: %d\nshort: %d\nunsigned short: %d\n", a, b, c);

        printf("------------------------------\n");
        a = 0b00000000000000000000000000000001; // int类型32位, 最高位是符号位
  sprintf(s, "%b", a);
        printf("二进制: %s\n", s);
  b =                 0b0000000000000001;  // short类型16位, 最高位是符号位
  c = b;  // unsigned short类型16位, 最高位不是符号位
  printf("int: %d\nshort: %d\nunsigned short: %d\n", a, b, c);
        
        printf("------------------------------\n");
        a = 0b00000000000000000111111111111111; // int类型32位, 最高位是符号位
  sprintf(s, "%b", a);
        printf("二进制: %s\n", s);
  b =                 0b0111111111111111;  // short类型16位, 最高位是符号位
  c = b;  // unsigned short类型16位, 最高位不是符号位
  printf("int: %d\nshort: %d\nunsigned short: %d\n", a, b, c);

        printf("------------------------------\n");
  a = 0b00000000000000001000000000000000; // int类型32位, 最高位是符号位
  sprintf(s, "%b", a);
        printf("二进制: %s\n", s);
  b =                 0b1000000000000000;  // short类型16位, 最高位是符号位
  c = b;  // unsigned short类型16位, 最高位不是符号位
  printf("int: %d\nshort: %d\nunsigned short: %d\n", a, b, c);

        printf("------------------------------\n");
        a = 0b00000000000000001111111111111111; // int类型32位, 最高位是符号位
  sprintf(s, "%b", a);
        printf("二进制: %s\n", s);
  b =                 0b1111111111111111;  // short类型16位, 最高位是符号位
  c = b;  // unsigned short类型16位, 最高位不是符号位
  printf("int: %d\nshort: %d\nunsigned short: %d\n", a, b, c);

        printf("------------------------------\n");
  a = 0b00000000000000010000000000000000; // int类型32位, 最高位是符号位
  sprintf(s, "%b", a);
        printf("二进制: %s\n", s);
  b =                 0b0000000000000000;  // short类型16位, 最高位是符号位
  c = b;  // unsigned short类型16位, 最高位不是符号位
  printf("int: %d\nshort: %d\nunsigned short: %d\n", a, b, c);

        printf("------------------------------\n");
  a = 0b00000000000000010000000000000001; // int类型32位, 最高位是符号位
  sprintf(s, "%b", a);
        printf("二进制: %s\n", s);
  b =                 0b0000000000000001;  // short类型16位, 最高位是符号位
  c = b;  // unsigned short类型16位, 最高位不是符号位
  printf("int: %d\nshort: %d\nunsigned short: %d\n", a, b, c);
        return 0;
}
输出:
二进制: 0
int: 0
short: 0
unsigned short: 0
------------------------------
二进制: 1
int: 1
short: 1
unsigned short: 1
------------------------------
二进制: 111111111111111
int: 32767
short: 32767
unsigned short: 32767
------------------------------
二进制: 1000000000000000
int: 32768
short: -32768
unsigned short: 32768
------------------------------
二进制: 1111111111111111
int: 65535
short: -1
unsigned short: 65535
------------------------------
二进制: 10000000000000000
int: 65536
short: 0
unsigned short: 0
------------------------------
二进制: 10000000000000001
int: 65537
short: 1
unsigned short: 1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-5 19:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表