unsigned 无符号数
以unsigned修饰的数据类型都是无符号的,即没有负数(或者说一般不表达负数)
但是,在如果给unsigned类型,如unsigned int b=-10;然后做运算,也是可行,原因是此表达式中,-10是以补码形式存入了无符号整数中;
详情下面代码
#include<stdio.h>
//打印无符号数的二进制形式
void print_b(unsigned int a)
{
char ch[33];
ch[32]='\0';
for(int i=0;i<32;i++)
ch[i]=((a>>(31-i))%2)+48;
printf("%s\n",ch);
}
int main(void)
{
unsigned int a,b;
int c=10;
a=10;
b=-9;
print_b(b);
if(b<0)
printf("b<0\n");
a+=b;
printf("a=%d\t a=%u\n",a,a);
printf("b=%d\t b=%u\n",b,b);
return 0;
}
结果:
可以看出来负数是以补码形式存在无符号整数中的,负数和正数相加的话,就会溢出形成真正的正整数,这就是为什么无符号数可以进行负数与正数的相加。
而printf使用不同的格式符会使无符号的负数打印出正数或负数。
下面是一道leetcode的算法题,其中就应用到了unsigned的用法:不使用+实现加法
int add(int a, int b)
{
int carry=((unsigned)a&b)<<1;//相加后进位的位
a=a^b;//相加后没有进位的位
//如果有进位就一直递归调用该加法函数,直到没有进位
//因为不能用+号,所以只能递归,不然直接return a+carry;即可
if(carry)
return add(a,carry);
return a;
}
其中的int carry=((unsigned)a&b)<<1;如果不加unsigned修饰的话,该加法只能适用于正数与正数的相加,无法与负数相加,原因是有符号数的情况下,左移操作不会移动符号位,这样进位就有了负数,然而进位不能为负数