专栏首页嵌入式大杂烩【C语言笔记】关于有符号数与无符号数的一些总结

【C语言笔记】关于有符号数与无符号数的一些总结

有、无符号数之间的运算

有符号数与无符号数之间的运算,编译器会进行隐式类型转换。

请看如下代码:

#include <stdio.h>
int main(void)
{
    unsigned int a = 6;
    int b = -20;

    if ( a+b > 6 )
        printf("a+b大于6\n");
    else
        printf("a+b小于6\n");

    return 0;
}

程序输出结果为:

a+b大于6

原因是因为编译器会将有符号数b转换成为一个无符号数,即此处a+b等价于a+(unsigned int)b

该程序运行在32bit环境下,b的值为0xFFFFFFFF-20+1 = 4294967276,即a+b将远远大于6。

C 语言按照一定的规则来进行此类运算的转换,这种规则称为正常算术转换,转换的顺序为:

double>float>unsigned long>long>unsigned int>int

即操作数类型排在后面的与操作数类型排在前面的进行运算时,排在后面的类型将隐式转换为排在前面的类型。

有、无符号数转化为更大类型

请看如下代码:

#include <stdio.h>
int main(void)
{
 //情况一
 signed char c1 = 0xff;  
 unsigned char c2 = 0xff;
 int a1,a2;
 a1 = (int)c1;
 a2 = (int)c2;
 printf("a1=%d(%#.8X),a2=%d(%#.8X)\n",a1,a1,a2,a2);

 //情况二
 signed char c3 = 0x80;
 unsigned char c4 = 0x80;
 int a3,a4;
 a3 = (int)c3;
 a4 = (int)c4;
 printf("a3=%d(%#.8X),a4=%d(%#.8X)\n",a3,a3,a4,a4);

 //情况三
 signed char c5 = 0x7f;
 unsigned char c6 = 0x7f;
 int a5,a6;
 a5 = (int)c5;
 a6 = (int)c6;
 printf("a5=%d(%#.8X),a6=%d(%#.8X)\n",a5,a5,a6,a6);
   return 0;
}

程序输出结果为:

a1=-1(0XFFFFFFFF),a2=255(0X000000FF)
a3=-128(0XFFFFFF80),a4=128(0X00000080)
a5=127(0X0000007F),a6=127(0X0000007F)

可见:

(1)将无符号数转换为更大的数据类型时, 只需简单地在开头添加0至所需位数,这种运算称为0扩展。

(2)将有符号数转换为更大的数据类型需要执行符号扩展,规则是将符号位扩展至所需的位数,即符号位为0时在开头添加0至所需位数,符号位为1时在开头添加1至所需位数。

此外,还需注意,对于一个signed char类型数据,0xff代表的是-1,因为整数在内存中是以补码的形式存储的。

正数的原码、反码、补码都相等。负数的反码是将原码中除符号位以外的所有位(数值位)取反,也就是 0 变成 1,1 变成 0;负数的补码是其反码加 1。

此处,对于一个signed char类型数据,-1的原码为1000 0001,反码为1111 1110,所以补码为1111 1111。

signed char的负数对应表为(图片来源于网络):

其中,-128最为特殊,需要特别记住,其不遵循传统的由补码计算原码的方法。

以上就是关于有符号数与无符号数的两点总结:(1)有符号数与无符号数之间的运算,编译器会进行隐式类型转换。(2)有符号数、无符号数转换为更大的数据类型。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【C语言笔记】函数参数压栈的顺序?

    按照日常习惯来看,C语言的函数参数压栈顺序是从左到右吧?但是事实却是相反的,C语言函数参数压栈顺序是从右到左的。下面看一个程序:

    正念君
  • 【C语言笔记】关于二维数组作为函数参数的问题

    大家觉得输出结果会是什么呢?结果是什么都没输出。出错原因是因为二维数组作为函数参数时要给出二维长度。但是,是不是就不能使用这个函数了呢?还是可以使用的,只要在主...

    正念君
  • 【C语言笔记】关于数组的一个陷阱!

    所以,&a[2] - &a[0]的结果是8?但是,事实不是这样的!!让我们把其结果打印出来:

    正念君
  • C#版 - 小红书后台开发面试题: 二维数组中的查找

    在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该...

    Enjoy233
  • 图论--网络流--最大流 POJ 2289 Jamie's Contact Groups (二分+限流建图)

    Jamie is a very popular girl and has quite a lot of friends, so she always keeps...

    风骨散人Chiam
  • 网络流--最大流--POJ 2139(超级源汇+拆点建图+二分+Floyd)

    FJ's cows really hate getting wet so much that the mere thought of getting caugh...

    风骨散人Chiam
  • codeforces 429A(dfs)

    给定一棵树,树的每个结点上有一个值,你可以对树上的值进行异或操作,求使树上的结点值成为目标值所需的最少操作

    dejavu1zz
  • 洛谷P1966 火柴排队(逆序对)

    首先要保证权值最小,不难想到一种贪心策略,即把两个序列中rank相同的数放到同一个位置

    attack
  • HDU 2665 Kth number(可持续化线段树)

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768...

    ShenduCC
  • HDU 1102 Constructing Roads(Kruskal)

    Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 6553...

    ShenduCC

扫码关注云+社区

领取腾讯云代金券