02-有符号与无符号

注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。

测试环境:ubuntu 14.04

一、计算机中的符号位

1)数据类型的最高位用于标识符数据的符号

 - 最高位为1,表明这个数为负数

 - 最高位为0,表明这个数为正数

有符号数的符号位
2-1.c

#include <stdio.h>

int main()
{
    char c = -5;
    short s = 6;
    int i = -7;
    
    printf("%d\n", ( (c & 0x80) != 0 ));	    //1
    printf("%d\n", ( (s & 0x8000) != 0 ));	    //0
    printf("%d\n", ( (i & 0x80000000) != 0 ));	//1

    return 0;
}

编译结果:

1
0
1

分析:

        c为负数,char型,8位,与0x80位与为0x80,最高位为1,表示负数

        s为正数,short型,16位,与0x8000位与为0x8000,最高位为0,表示正数

        i为负数,int型,32位,与0x80000000位与为0x80000000,最高位为1,表示负数

二、有符号数的表示法

1)在计算机内部用补码表示有符号数

 - 正数的补码为正数本身

 - 负数的补码为负数的绝对值各位取反后加1

如:

8位整数5的补码为:   0000 0101

8位整数-7的补码为:  1111 1001

16位整数20的补码为: 0000 0000 0001 0100

16位整数-13的补码为:1111 1111 1111 0011

--------------------------------------------------------------------------

有符号数越界时:

char max = 0x7f;		        //127  
printf("max = %d\n" , max);	//127 
printf("max = %x\n" , max);	//0111 1111
printf("===================\n");
max = max + 1;			//-128
printf("max = %d\n" , max);	//-128
printf("max = %x\n" , max);	//1000 0000
printf("===================\n");
max = max + 1;			//-127
printf("max = %d\n" , max);	//-127
printf("max = %x\n" , max);	//1000 0001
printf("===================\n");

结论:

越界数值后直接变到负最大,再累加就递减。

三、无符号数的表示法

1.在计算机内部用原码表示无符号数

  - 无符号数默认为正数

  - 无符号数没有符号位

2.对于固定长度的无符号数

   - MAX_VALUE + 1 -> MIN_VALUE

   - MIN_VALUE - 1 -> MAX_VALUE

四、signed和unsigned

1)C语言中变量默认为有符号的类型

2)unsigned关键字声明关键字声明变量为无符号类型

#include <stdio.h>

int main()
{
	int i;		    //默认为带符号整型
	signed int j;  	//显示声明变量为符号整型
	unsigned int k;	//声明变量为无符号整型

	return 0;
}

    注意:C语言中只有整数类型能够声明unsigned变量。 浮点数不可以用unsigned。

当无符号数遇见有符号数

#include <stdio.h>

int main()
{
 
    unsigned int i = 5;
    int j = -10;
    
    if( (i + j) > 0 )   //执行i+j>0 也就是int j被转换成unsigned int都是正数
    {
        printf("i + j > 0\n");
    }
    else
    {
        printf("i + j <= 0\n");
    }
    
    return 0;
}	

运行结果:

i + j > 0

分析:

         当有符号数遇见无符号数时,混合运算时,有符号型就会被转换成无符号数。这样就会变成很大一个正数,因此执行了 i+j>0。

2) 将int型变量i改成char型

#include <stdio.h>

int main()
{
 
    char i = 5;
    int j = -10;
    
    if( (i + j) > 0 )   //执行i+j>0 也就是int j被转换成unsigned int都是正数
    {
        printf("i + j > 0\n");
    }
    else
    {
        printf("i + j <= 0\n");
    }
    
    return 0;
}	

运行结果:

i + j <= 0

分析:

        char型隐式转换成int型,然后正确相加,结果小于0,打印:i + j <= 0 

错误的使用了unsigned

#include <stdio.h>

int main()
{
    unsigned int i = 0;
    
    for(i=9; i>=0; i--)		//i为无符号类型,当i = 0时,继续递减会变到最大值
    {
        printf("i = %u\n", i);
    }
    
    return 0;
}

打印结果:

无限打印,死循环。

分析:

        i为无符号类型,当i = 0时,继续递减会变到最大值。

小结

1) 有符号数用补码表示

     - 正数的符号位为0

     - 负数的符号位为1

2) 无符号数用原码表示

     - 无符号数没有符号位

     - 无符号数只用于表示正数

3) unsigned只能修饰整数类型的变量

当无符号数与有符号数混合计算时,会将有符号数转换为无符号数后再进行计算,结果为无符号数。

发布了40 篇原创文章 · 获赞 1 · 访问量 1789

猜你喜欢

转载自blog.csdn.net/piaoguo60/article/details/83006151