我们在 C 语言中经常会见到 unsigned 关键字,那么这是什么意思呢?在计算机内,数据类型分为有符号和无符号两种类型。它的最高位用于标识数据的符号:如果最高位为 1,表明这个数为负数;如果是0的则表明这个数为正数。那么我们就来做个试验验证下,代码如下所示:
#include <stdio.h> int main() { char c = -5; short s = 6; int i = -7; printf("c : %d\n", ( (c & 0x80) != 0 )); printf("s : %d\n", ( (s & 0x8000) != 0 )); printf("i : %d\n", ( (i & 0x80000000) != 0 )); return 0; }
c 为负数最高位为1,理论上 & 之后应该不等于0,所以打印的会是1;s 为正数最高位为0,,理论上 & 之后应该等于0,打印的会是0;i 位负数,会打印1。下来我们在 Linux 环境中用 gcc 编译下,看看结果是否和我们分析的一致,结果如下:
我们打印的结果也从侧面证实了我们的分析是对的。那么在计算机内部是怎样表示有符号数的呢?答案用补码来表示,正数的补码为正数本身,负数的补码为负数的绝对值各位取反后加1。我们来分析下 -7 的补码是多少?
-7 ==> |-7| + (末位+1)==> 111 + 1==> 0000 0111 + 1 ==> 1111 1000 + 1 ==> 1111 1001
这是我们分析的结果,那么我们用计算器转换下看看,是否和我们分析的一致呢?
我们看到结果和我们分析的是一致的。在计算机内部用原码表示无符号数,无符号数默认为正数,无符号数没有符号位。对于固定长度的无符号数,MAX_VALUE + 1 ==> MIN_VALUE,MIN_VALUE - 1 ==> MAX_VALUE。
在 C 语言中变量默认为有符号的类型,unsigned 关键字声明变量为无符号类型。注意:C 语言中只有整数类型能够声明 unsigned 变量。下来我们再做个试验,代码如下:
#include <stdio.h> int main() { unsigned int i = 5; int j = -10; if( (i + j) > 0 ) { printf("i + j > 0\n"); } else { printf("i + j <= 0\n"); } return 0; }
我们当然会认为这个程序输出的是 i + j <= 0,可事实是这样吗?我们来编译下,得到结果如下:
结果和我们想的不一样,那么这是怎么回事呢?原来在计算机内部,当有符号数和无符号数混合运算时,计算机将自动的将有符号数转换为无符号数后再进行计算,结果为无符号数。那么这个程序输出的结果当然是大于0的啦。
我们在这块要注意一个陷阱,那就是错误的使用了 unsigned 。我们来看这样一个例子,代码如下:
#include <stdio.h> int main() { unsigned int i = 0; for(i=9; i>=0; i--) { printf("i = %u\n", i); } return 0; }
在我们的认为中,这个程序会输出 0-9 就完了,那么真是这样吗?我们编译下,看看结果
结果就是如上图所示,那么这些这么的大的数字是在哪打印出来的呢?程序在不停输出,不得已中断程序的运行。仔细的看看我们的示例代码,我们定义的是 unsigned int 类型的,无符号类型的。因而它是一直大于0的,在减到0的时候,再次减1就是 2^32 - 1 了。为什么是32呢?因为在 Linux 中,int 型数据是 4 个字节,每个字节占 8 bit,所以一共占 32 bit位。
那么我们本节学习了有符号数与无符号数。有符号数用补码表示:正数的符号位为0,负数的符号位为1。无符号数用原码表示:无符号数没有符号位,无符号数只用于表示正数。unsigned 只能修饰整数类型的变量,当有符号数和无符号数混合运算时,计算机将自动的将有符号数转换为无符号数后再进行计算,结果为无符号数。后面我们会继续学习 C 语言的相关知识。
欢迎大家一起来学习 C 语言,可以加我QQ:243343083。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。