查看原文
其他

【重要】关于有符号数与无符号数的一些总结

正念君 嵌入式大杂烩 2021-01-31


1

有、无符号数之间的运算


有符号数与无符号数之间的运算,编译器会进行隐式类型转换

请看如下代码:

#include <stdio.h>
int main(void)
{
 unsigned int a = 6;
 int b = -20;
 
 if ( a+b > 6 )
   printf("a+b大于6\n");
 else
   printf("a+b小于6\n");
 
   return 0;
}


程序输出结果为:

a+b大于6


原因是因为编译器会将有符号数b转换成为一个无符号数,即此处a+b等价于a+(unsigned int)b。


该程序运行在32bit环境下,b的值为0xFFFFFFFF-20+1 = 4294967276,即a+b将远远大于6。


C 语言按照一定的规则来进行此类运算的转换,这种规则称为正常算术转换,转换的顺序为:

double>float>unsigned long>long>unsigned int>int


即操作数类型排在后面的与操作数类型排在前面的进行运算时,排在后面的类型将隐式转换为排在前面的类型。


2


有、无符号数转化为更大类型


请看如下代码:

#include <stdio.h>
int main(void)
{
 //情况一
 signed char c1 = 0xff;  
 unsigned char c2 = 0xff;
 int a1,a2;
 a1 = (int)c1;
 a2 = (int)c2;
 printf("a1=%d(%#.8X),a2=%d(%#.8X)\n",a1,a1,a2,a2);
 
 //情况二
 signed char c3 = 0x80;
 unsigned char c4 = 0x80;
 int a3,a4;
 a3 = (int)c3;
 a4 = (int)c4;
 printf("a3=%d(%#.8X),a4=%d(%#.8X)\n",a3,a3,a4,a4);
 
 //情况三
 signed char c5 = 0x7f;
 unsigned char c6 = 0x7f;
 int a5,a6;
 a5 = (int)c5;
 a6 = (int)c6;
 printf("a5=%d(%#.8X),a6=%d(%#.8X)\n",a5,a5,a6,a6);
   return 0;
}


程序输出结果为:

a1=-1(0XFFFFFFFF),a2=255(0X000000FF)
a3=-128(0XFFFFFF80),a4=128(0X00000080)
a5=127(0X0000007F),a6=127(0X0000007F)


可见:

(1)将无符号数转换为更大的数据类型时, 只需简单地在开头添加0至所需位数,这种运算称为0扩展。


(2)将有符号数转换为更大的数据类型需要执行符号扩展,规则是将符号位扩展至所需的位数,即符号位为0时在开头添加0至所需位数,符号位为1时在开头添加1至所需位数。


此外,还需注意,对于一个signed char类型数据,0xff代表的是-1,因为整数在内存中是以补码的形式存储的。


正数的原码、反码、补码都相等。负数的反码是将原码中除符号位以外的所有位(数值位)取反,也就是 0 变成 1,1 变成 0;负数的补码是其反码加 1。


此处,对于一个signed char类型数据,-1的原码为1000 0001,反码为1111 1110,所以补码为1111 1111。


signed char的负数对应表为(图片来源于网络):



其中,-128最为特殊,需要特别记住,其不遵循传统的由补码计算原码的方法。


以上就是关于有符号数与无符号数的两点总结:(1)有符号数与无符号数之间的运算,编译器会进行隐式类型转换。(2)有符号数、无符号数转换为更大的数据类型。


推 荐 阅 读

【常见】getchar()、getche()、getch()区别?
【知识点】#define与typedef的区别?
【常用】static有几种用法?

【常用】extern怎么用?

【易错】char *str与char str[]的区别?

【提高效率】你应该用复合赋值语句?

【知识点】来看一看volatile关键字

【知识点】C语言变量默认的初值是?

【易错】C语言内存对齐问题

【实用】关于数组与指针的总结

【编程练习】进制转换问题

【本质】你知道C语言编译的过程吗?



【每日一句】

你的人生永远不会辜负你的。那些转错的弯,那些走错的路,那些流下的泪水,那些滴下的汗水,那些留下的伤痕,全都让你成为独一无二的自己。






    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存