C语言进阶:2、有符号和无符号

数据类型的最高位(二进制)用于标识数据的符号:

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

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

示例代码:

#include <stdio.h>

int main()
{
	int sign = 0;
	
	char a = -5;
	short b = 1; //两个字节
	int c = -1;
	
	sign = ((a & 0x80) != 0);
	printf("%d\n", sign);
	sign = ((b & 0x8000)!= 0);
	printf("%d\n", sign) ;
	sign =((c & 0x80000000) != 0);
	printf("%d\n", sign);

	return 0;
}

运行上面代码,通过与0x80、0x8000、0x80000000进行按位与操作,来判断a、b、c的二进制数最高位。

1
0
1

在计算机中,用补码来表示有符号数。

正数的补码为正数本身,负数的补码为负数的绝对值,然后各位取反后加1;

-7 ==》7 ==》 111 ==》 0000 0111 ==》 1111 1000 ==》 1111 1001;

在计算机内部用原码表示无符号数,无符号数默认为正数,且没有符号位;

对于固定长度的无符号数,最小值为0.

 MAX_VALUE + 1 -> MIN_VALUE;
 MIN_VALUE - 1 -> MAX_VALUE;

最大值根据占用内存大小(数据类型)决定。

C语言中默认变量为有符号的类型,unsigned关键字声明变量为无符号类型。

int i; 有符号;
signed int j ; 显式声明为有符号数;
unsigne int l;  声明为无符号数

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;
}

在linux Gcc下编译后运行结果为:

delphi@delphi-vm:~/will$ ./a.out
 (i + j) > 0

原因在于,有符号数在和无符号数进行运算时,会自动转换为无符号数。

观察下面代码,判断输出:

int main()
{
	unsigned int i = 0;
	
	for(i = 9; i>=0; i--)  //注意此处i的范围  i>= 0
	{
		printf("%u\n", i);
	}
	return 0;	
}

程序运行后进去死循环。

原因在于无符号数的特点:

 MAX_VALUE + 1 -> MIN_VALUE;
 MIN_VALUE - 1 -> MAX_VALUE;
划重点:当无符号数和有符号数进行混合运算时,会将有符号数转换为无符号数后再进行计算,结果为无符号数。









猜你喜欢

转载自blog.csdn.net/qq_28388835/article/details/80152733