C之有符号与无符号(二)

        我们在 C 语言中经常会见到 unsigned关键字,那么这是什么意思呢?在计算机内,数据类型分为有符号和无符号两种类型。它的最高位用于标识数据的符号:如果最高位为 1,表明这个数为负数;如果是0的则表明这个数为正数。那么我们就来做个试验验证下,代码如下所示:

创新互联专注于道里网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供道里营销型网站建设,道里网站制作、道里网页设计、道里网站官网定制、重庆小程序开发公司服务,打造道里网络公司原创品牌,更为您提供道里网站排名全网营销落地服务。

#include 

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 编译下,看看结果是否和我们分析的一致,结果如下:

C之有符号与无符号(二)

        我们打印的结果也从侧面证实了我们的分析是对的。那么在计算机内部是怎样表示有符号数的呢?答案用补码来表示,正数的补码为正数本身,负数的补码为负数的绝对值各位取反后加1。我们来分析下 -7 的补码是多少?

        -7 ==> |-7| + (末位+1)==> 111 + 1==> 0000 0111 + 1 ==> 1111 1000 + 1 ==> 1111 1001

这是我们分析的结果,那么我们用计算器转换下看看,是否和我们分析的一致呢?

C之有符号与无符号(二)C之有符号与无符号(二)

        我们看到结果和我们分析的是一致的。在计算机内部用原码表示无符号数,无符号数默认为正数,无符号数没有符号位。对于固定长度的无符号数,MAX_VALUE + 1 ==> MIN_VALUE,MIN_VALUE - 1 ==> MAX_VALUE。

        在 C 语言中变量默认为有符号的类型,unsigned关键字声明变量为无符号类型。注意:C 语言中只有整数类型能够声明 unsigned 变量。下来我们再做个试验,代码如下:

#include 

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,可事实是这样吗?我们来编译下,得到结果如下:

C之有符号与无符号(二)

        结果和我们想的不一样,那么这是怎么回事呢?原来在计算机内部,当有符号数和无符号数混合运算时,计算机将自动的将有符号数转换为无符号数后再进行计算,结果为无符号数。那么这个程序输出的结果当然是大于0的啦。

        我们在这块要注意一个陷阱,那就是错误的使用了 unsigned 。我们来看这样一个例子,代码如下:

#include 

int main()
{
 
    unsigned int i = 0;
    
    for(i=9; i>=0; i--)
    {
        printf("i = %u\n", i);
    }
    
    return 0;
}

        在我们的认为中,这个程序会输出 0-9 就完了,那么真是这样吗?我们编译下,看看结果

C之有符号与无符号(二)

        结果就是如上图所示,那么这些这么的大的数字是在哪打印出来的呢?程序在不停输出,不得已中断程序的运行。仔细的看看我们的示例代码,我们定义的是 unsigned int 类型的,无符号类型的。因而它是一直大于0的,在减到0的时候,再次减1就是 2^32 - 1 了。为什么是32呢?因为在 Linux 中,int 型数据是 4 个字节,每个字节占 8 bit,所以一共占 32 bit位。

        那么我们本节学习了有符号数与无符号数。有符号数用补码表示:正数的符号位为0,负数的符号位为1。无符号数用原码表示:无符号数没有符号位,无符号数只用于表示正数。unsigned只能修饰整数类型的变量,当有符号数和无符号数混合运算时,计算机将自动的将有符号数转换为无符号数后再进行计算,结果为无符号数。后面我们会继续学习 C 语言的相关知识。


         欢迎大家一起来学习 C 语言,可以加我QQ:243343083。


本文名称:C之有符号与无符号(二)
标题来源:http://myzitong.com/article/jejijs.html