C语言丨关键字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

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 ", sub_result ); //分析输出 255

printf( "%d ", 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类型的数一般要在输入和输出的时候刻意去注意。

文章参考来源:

https://blog.csdn.net/wen381951203/article/details/79922220

https://blog.csdn.net/Johan_Joe_King/article/details/84201039


 

如果你想更好的提升你的编程能力,学好C语言C++编程!弯道超车,快人一步!

C语言C++学习企鹅圈子】,分享(源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

编程学习书籍:


 

编程学习视频:


 
原文地址:https://www.cnblogs.com/mu-ge/p/14330046.html