signed和unsigned的使用与区别详解

signed 和 unsigned

在C语言中,signed/unsigned用于修饰整数变量,signed表示有符号的,unsigned表示无符号的。 今天就带大家了解一下 关键字signed和unsigned 。

1、signed

sign的本意是“标记,做记号”,ed后缀有一种完成时的感觉,这里表示的是有符号的。
signed关键字是ISO/ANSI C90标准新增的,其常见于整数类型的符号规定处 。
signed的作用是:声明有符号类型的整数类型。
其实说signed很常见也不见得,因为我们常用的int、short和long,以及long long,默认情况下都是signed有符号的。所以相比起来unsigned的戏份可能比signed更多,signed在这里只是相当于刻意地去说明其后面的变量是有符号类型的

signed int a; /* 通常这里带signed的变量定义都可以省略掉signed,因为signed本身就是默认的 */
signed short int b;
signed short c;
signed long int d;
signed long e;
signed long long f;
unsigned int g; /* 写上signed后,上面的定义似乎在刻意地大声说“上面这些变量应该是有符号的” */
unsigned short h; /* 但一般unsigned的戏份还是比signed多,signed关键字和auto关键字的宿命类似 */

有符号数在计算机中的的表示方法:在计算机内部,是用补码表示有符号数

- 正数的补码是其本身
- 负数的补码为负数的绝对值得各个位取反加1
举个例子:
8位整数 5的补码为:0000 0101
8位整数 -7的补码为:取绝对值|-7| = 7 --> 二进制为 0000 0111 --> 各个位取反 1111 1000 -->最后加1 -->1111 1001,所 以-7在计算机中就表示为1111 1001。
16位整数 20的补码为:0000 0000 0001 0100
16位整数 -13的补码为:1111 1111 1111 0011(可自行推导)

2.unsigned

unsigned意为“没有标记过的”,在C语言中表示无符号的,与关键字signed对应
这个关键字在很多头文件的变量定义中还是很常见的,一般用在整数类型的符号说明处
unsigned的作用是:声明无符号的整数类型
unsigned的使用和signed类似,unsigned一般加在int等整数类型名称前:

/* unsigned可以修饰的几种类型 */
unsigned int a; /* 无符号整型 */
unsigned short b; /* 无符号短整型 */
unsigned long c; /* 无符号长整型 */
unsigned long long d; /* 无符号long long类型 */

引入signed和unsigned的概念后,就要严格注意输入输出时候的格式了

printf("%d, %u", a, b); /* %u是unsigned类型的说明符 */
printf("%u, %d", a, b); /* 如果对signed类型的变量用%u,那就不会去找内存中的符号位,全部当数字位处理 */
/* 这时显示的结果可能与signed本身想表达的值差异很大,数字0情况除外 */
unsigned short c = 4;
printf("%hu"); /* %h是短整型,%hu表示无符号短整型 */
unsigned long d = 5;
printf("%lu"); /* %l是长整型,%lu表示无符号长整型 */

对于long和long long常量,能使用后缀直接给出unsigned的属性:

120L; /* L后缀表示long常量 */
120LU; /* 再加上U后缀表示unsigned */
120LLU; /* LLU表示unsigned long long */
120ull; /* ull这样写也对 */

无符号数在计算机中的表示方法:计算机用原码表示无符号数
- 无符号数默认为正数n
-无符号数没有符号位无符号数最小值为0,最大值为其所占的位数全为1时的值
例如

8位无符号整数,最小值为0,最大值为二进制1111 1111,转换为十进制就是255。
对于固定长度的无符号数:
MAX_VALUE + 1 = MIN_VALUE
MIN_VALUE - 1 = MAX_VALUE

C语言中变量默认 为有符号的类型,如要将变量声明为无符号数,则需要使用unsigned关键字(C语言中只有整数类型能够声明为unsigned无符号变量)

#include<stdio.h>
int main()
{
int i; //默认i为有符号数
signed int j; //显示声明j为有符号数
unsigned char min_value = 0; //显示声明k为无符号数
unsigned char max_value = 255;
unsigned char sub_result = min_value - 1; //无符号数最小值 - 1 = 最大值
unsigned char add_result = max_value + 1; //无符号数最大值 + 1 = 最小值
printf( "%d\n", sub_result ); //分析输出 255
printf( "%d\n", add_result ); //分析输出 0
return 0;
}

输出结果 :

255
0

3、signed和unsigned的区别

signed和unsigned用于修饰整数类型(包括char,从ANSI C89标准开始支持)
signed是默认的 ,表示这个变量是有符号的, 也就是可以存储整数和负数
unsigned则需要显示给出,表示这个变量没有符号值能存储数的大小,而不能表示正负
signed存储符号是有代价的,代价就是存储空间中的一个比特位,专门用来存储符号,这一位不能表示数值
所以 ,一般来说 ,同类型的signed能够存储的数的绝对值大小要小于unsigned
默认的int、short、long、long long为有符号数;换言之,int等价于signed int,short等价于signed short,long等价于signed long,long long等价于signed long long。
但是char本身是signed char还是unsigned char,取决于语言的实现(编译器)。
数据类型范围列表如下:
在这里插入图片描述
总之,signed和unsigned的区别基本就在于,是否把存储的某一位看做符号位,unsigned时不看符号位,所以unsigned一般表示的是非负数
注意:
整数类型占多少字节空间是不确定的,只能保证sizeof(short) <= sizeof(int) <= sizeof(long)。
在32位的设备平台上,short为16位(2字节), int为32位(4字节),long为32位(4字节),long long为64位(8字节)。
在64位的设备平台上,short为16位(2字节), int为32位(4字节),long为64位(8字节),long long为64位(8字节)。

4、为什么一定要区分signed和unsigned?

看两种情况:signed和unsigned分别存储正数和负数,默认最高位为符号位

(1)正数6,分别用signed和unsigned方式在一个字节中存储:0000 0110 [signed] 0000 0110 [unsigned]

(2)int类型的负数-5和正数4294967291在4个字节中的存储:FFFF FFFB [十六进制]

上述例子有一个特点,就是不同变量在内存中的存储形式是一样的

由于0表示正,所以signed和unsigned的正数在内存中的表示是一样的

而同样的一个存储,在signed和unsigned下就可能表示两个不同的数(0除外)

所以unsigned类型的数一般要在输入和输出的时候刻意去注意。

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值