C语言无符号数赋值为负数时的%d%u输出问题解释

问题发现

近日在练习过程中发现无符号整形数如果赋值为“-1”可以用%d进行输出,从而得到问题
代码如下

#include<stdio.h>
int main()
{
	unsigned int e = -1;  //输出结果是-1,说明这里无符号整形也能储存-1,问题不明 
	printf("unsigned int=%d\n",e);
	return 0;
 } 

结果如下:

unsigned int=-1

什么是无符号整形

在书中说明整形为 int 无符号整形为 unsigned int
int在储存数据空间中最高位代表数据的正负(0为正,1为负)
unsigned int 在储存中所有数据空间皆为数据值,但只能存放正数。
所以可以存放的正数范围比整形变量大一倍

例如int空间为4个字节,所以unsigned int 也为4个字节,但第一位可以表示数据而不是符号。则有以下补码:

int a =1:

00000000000000000000000000000001

int b =-1:

10000000000000000000000000000001

最大值int max = 2147483647 (231-1)

01111111111111111111111111111111

最大值unsigned int Max = ‭4294967295‬ (232-1)

11111111111111111111111111111111

补码的计算

正整数的补码是其二进制表示,与原码相同

例:+9的补码是00001001。(备注:这个+9的补码是用8位2进制来表示的,补码表示方式很多,还有16位二进制补码表示形式,以及32位二进制补码表示形式,64位进制补码表示形式等。每一种补码表示形式都只能表示有限的数字。)

求负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1 。
同一个数字在不同的补码表示形式中是不同的。
比如-15的补码,在8位二进制中是11110001,然而在16位二进制补码表示中,就是1111111111110001。以下都使用8位2进制来表示。

例:求-5的补码。
-5对应正数5(00000101)→所有位取反(11111010)→加1(11111011)
所以-5的补码是11111011。

无符号整形的输出

无符号整形在输出时要用%u格式来进行输出(十进制无符号数),若赋值为负值则会输出错误(如int类型负数)

例如:

正确时:

	unsigned int a = 30;
	printf("unsigned int=%u\n",a);

输出为

	30

错误时:

	unsigned int a = -30;
	printf("unsigned int=%u\n",a);

输出为

	4294967266

问题解决

int用%d和%u输出

在查阅资料后发现,C中%d与%u的区别是程序如何去解释这一变量的数据
所以,%d在解释过程中第一位数据代表了符号,%u第一位数据代表了数据值
在输出一下数据时就有:

int a = -1;
printf("%d\n%u",a);
-1
4294967295

因为-1的补码为

11111111111111111111111111111111

%d解释过程:

1.第一位是1,所以为负值。
2.由补码再求补码,得到以下补码

10000000000000000000000000000001

3.输出结果 -1

%u解释过程:
直接将其按源码处理,所以值为232-1 = 4294967295

unsigned int用%d和%u输出

经过上面的讨论,有如下代码

unsigned int a = -1;
printf("%d\n%u",a);

输出为

-1
4294967295

同理,在赋值时,-1的源码被转换为补码:

11111111111111111111111111111111

所以在赋值到unsigned int 中时也是相同的,所以在经过%d%u解释后输出的值仍为-1 和 4294967295。其他负数值同理。

  • 31
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值