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

我们在 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。

原文地址:http://blog.51cto.com/12810168/2095061

时间: 2024-08-07 22:45:06

C之有符号与无符号(二)的相关文章

C语言 有符号、无符号

C语言 有符号.无符号 有符号无符号说明 一.有符号 signed char 8bit 取值范围:-2^7 ~ 2^7-1 . -128~127 int 32bit 取值范围:-2^31 ~ 2^31-1 . -2147483648~2147483647 long long 64bit 取值范围:-2^63 ~ 2^63-1 #include <stdio.h> int main() { signed int a = -1089474374; //定义有符号整型变量a printf("

有符号和无符号类型运算

#include <iostream> int main() { unsigned i = 10 , j = 30 ; int m = -42 , n = 30 ; std::cout<<i-j<<std::endl; std::cout<<m*i<<std::endl; std::cout<<unsigned(-420)<<std::endl; return 0 ; } 结论:有符号和无符号类型相运算(加减乘除),先运算

int类型有符号与无符号内存中 -- C

/* int 有符号 0xffffffff == -1 0xfffffffe == -2 最小 0x80000000 == -21 4748 3648 最大 0x7fffffff == 21 4748 3647 0x00000001 == 1 0x00000000 == 0 int 无符号 最大 0xffffffff == 42 9496 7295 0x80000000 == 21 4748 3648 0x7fffffff == 21 4748 3647 最小 0x00000000 == 0 *

C语言的有符号与无符号,二进制整数的扩展与截断

前一节说了整数的表示方式,,也就是无符号编码与补码编码.这一届说一下二进制整数的扩展与截断,这部分内容与C语言挂钩.so,我们先看以下C语言的有符号和无符号数. C语言中的有符号数和无符号数 有符号数和无符号数的本质区别其实就是采用的编码不同,前者采用补码编码,后者采用无符号编码. 在C语言中,有符号数和无符号数是可以隐式转换的,不需要手动实施强制类型转换.不过也正是因为如此,可能你一不小心就将一个无符号数赋给了有符号数.就会造成出乎意料的结果,就像下面这样: #include <stdio.h

结构体位制 中存在 有符号 与 无符号 -- C

#include <stdio.h> #include <stdlib.h> #include <string.h> /* 有符号 结构体1 */ struct bits { int b1:5; /* 因为是int型,最大设置32位,由于int型是有符号整形, 所以这里5位为有符号类型. 11111 -1 10000 -16 01111 15 00000 0 */ int :2; int b2:2; /* 11 -1 10 -2 01 1 00 0 */ int b3:

Verilog -- 有符号与无符号运算

目录 Verilog中有符号与无符号的加法和乘法运算 无符号乘法和加法 有符号乘法和加法 有符号和无符号运算 参考: https://blog.csdn.net/vivid117/article/details/101427302 http://wscentity.lofter.com/post/1d00edbd_6476453 Verilog中有符号与无符号的加法和乘法运算 无符号乘法和加法 对于无符号的乘法和加法,没有什么好说的,就是直接用'*'和'+'. 有符号乘法和加法 有符号和无符号运

Java-java中的有符号,无符号操作以及DataInputStream

1. 无符号和有符号 计算机中用补码表示负数,并且有一定的计算方式:另外,用二进制的最高位表示符号,0表示正数.1表示负数.这种说法本身没错,可是要有一定的解释,不然它就是错的,至少不能解释,为什么字符类型的-1二进制表示是“1111 1111”16进制表示为FF,而不是1000 0001. 在计算机中,可以区分正负的类型,称为有符号类型,无正负的类型,称为无符号类型. 使用二进制中的最高位表示正负 一个字节为8位,按0开始记,那它的最高位就是第7位,2个字节,最高位就是15位,4个字节,最高位

解协议时有符号和无符号整形处理

来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=309GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com 1.问题:网关解析正确,我.net这边解析错误,原因是,本来是无符号的,我搞成了有符号的了. 3.WORD:无符号双字节整形 5.0x800A转十进制为32758 原因是:以下两种写法是等价的,IPAddress.NetworkToHostOrder()不能接收UInt16类型,所

有符号和无符号整型数字

8位无符号整型:0 -> 25511111111     255...10000000     12801111111     127...00000000       0 8位有符号整型:-128 -> 12701111111    127...00000000      011111111     -1        取反加一...10000000   -128        取反加一