热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c语言中无符号数,c语言无符号数

1.在C语言中,数字常量如果没有后缀‘U或u,则默认为是有符号数。例:[cpp]viewplain

1. 在C语言中,数字常量如果没有后缀‘U'或'u',则默认为是有符号数。

例:

[cpp]  view plain  copy unsigned int n = 1024;    unsigned int m = 0XFF;  

其中1024和oxff这两个常量都是有符号数,这就意味着每个赋值操作包含了一个隐式的由有符号数到无符号数的类型转换。
而1024u和0xffu则视为无符号数。

2. 同类型整数之间的类型转换: 这样的类型转换是指不同字长的无符号数或有符号数之间的类型转换,如由short转为int,或是有unsigned short转换为unsigned。
无符号数由短变长使用零扩展,使用0来填充多出来的高字节。

例:

[cpp]  view plain  copy unsigned char a = 178;   unsigned short b = a;  

a的二进制表示为1011,0010,b的二进制表示为0000,0000,1011,0010,这就是零扩展。零扩展对于应汇编(ia32)指令movz。

有符号数一般使用补码表示,有符号数的由短变长的转换使用符号扩展,即较短的数的二进制表示的最高位是0则用零扩展,同无符号数的零扩展,而如果是1,则用1来补充缺少的位。

例:

[cpp]  view plain  copy char a = -78;   short b = a;  

a的二进制表示为1011,0010,b的二进制表示为1111,1111,1011,0010。当然,此时b的大小仍是-78。

而由长变短则更简单,直接截断即可,高位的字节直接丢掉,低位的字节保持不变。




3. 有符号数和无符号数之间进行类型转换: [cpp]  view plain  copy a = (int)b; // 显示的强制类型转换   b = a;      // 转换是隐式发生的  

当发生有符号数和无符号数之间的强制类型转换时,如果他们的长度是相同(比如int和unsigned一般都是4个字节,short和unsigned short都是两个字节),那么在位一级的表示上并没有变化,即如果都转化为二进制的形式来看,都是一样的。虽然从二进制01组成的角度来看是一样的,但我们要知道有符号数和无符号数的区别是最高位的权值发生了变化,有符号整数用补码表示,最高位的权值是-2^(w-1),w为位宽,如int类型w大小为32,而无符号整数的最高为的权值为2^(w-1)。而如果两个数长度不同,则先进行前面提到的2中长度的转换,再进行类型转换。

4. 有符号数和无符号数在一起进行运算时,要首先将有符号数转换为无符号数,再进行运算。

例:

[cpp]  view plain  copy short n = -1;   unsigned short m = 1;   if(m > n) printf("m > n");   else printf("m < n");  

这样可以得到什么结果呢?

首先n转化为无符号数,大小为65535,所以输出是m


5. 整型常量

在1中我们说,如果一个常数没有后缀,那么默认的是int类型,如果后缀是u,则默认为unsigned int。但这样的说法并不完整。

首先,我们默认了常数的格式是十进制,但是十六进制的也很常用。

然后,还可能出现这样的情况:给出的常数的值已经超越了int或是unsigned int的范围。这种情况又该如何处理?

可能目前为止都没有遇到过这种情况,但是如果发生该如何理解呢?别急,C标准对这些情形都给出了明确的说明,了解之后你就会知道为啥不知道也没有发生错误。

看完下面这张表你也许悟到了点啥,莫名其妙也没关系,让我们来细说一例:

“十进制常数”和“none”后缀的对应的格子里的内容是:

int

long int

long long int

这三行的意思是对于没有后缀的十进制常数,如1024和3147483647,首先用int类型来匹配,int类型值得范围是-2147483648~2147483647(这里可以看出有符号整型的范围不是对称的,而且此处默认int类型为32位),1024在此范围之内,那么这个常数的类型就是int了,但3147483647不在此范围之内,即int类型罩不住,那么看第二行, long int 类型, 其范围还依赖于机器的字长,一般32位机上为-2147483648~2147483647,还是罩不住,再看第三行,long long int,其范围是-9223372036854775808到9223372036854775807,所以3147483647最终匹配的类型是long long int。

对于八进制或十六进制的常数,如果没有后缀,会先匹配有符号数,再匹配无符号数,毕竟从取值的绝对值的范围的角度上看无符号数更广。

如果一个常数大的表中没有任何类型能够表示,那么就要看有没有扩展类型能够表示它,如果没有,那么这个常数没有类型。

-2147483648这个常数会是什么类型?不一定是int类型,这还要看编译器,很可能编译器会把它当成一个64位的有符号整型(可能是long long int),或者说该编译器在识别常数时可能认为int类型的范围是-2147483647~2147483647,但是我们应该知道32位的int类型是可以表示-2147483648。所以求int类型的绝对值也不那么简单,需要考虑这种情况。


Suffix 
后缀Decimal Constant 
十进制常数Octal or Hexadecimal Constant 
八或十六进制常数noneint
long int
long long intint
unsigned int
long int
unsigned long int
long long int
unsigned long long intu or Uunsigned int
unsigned long int
unsigned long long intunsigned int
unsigned long int
unsigned long long intl or Llong int
long long intlong int
unsigned long int
long long int
unsigned long long intBoth u or U
and l or Lunsigned long int
unsigned long long intunsigned long int
unsigned long long intll or LLlong long intlong long int
unsigned long long intBoth u or U
and ll or LLunsigned long long intunsigned long long int


我们知道,C代码会被编译为针对某种处理器架构的汇编代码,然后生成机器码,机器码才能够被cpu执行。在C代码时看起来很简单的逻辑,变为机器码后就很难读懂了,也就是说C代码比汇编代码和机器码对人类来说有更好的可读性。我们也知道一般用C语言进行底层开发,如开发Linux操作系统,为什么不用java呢,因为C语言更硬一些,更方便对硬件功能进行抽象描述,C语言在高级语言中并不那么高级。C标准中,整数分为有符号整数和无符号整数,但是归根到底是要放到寄存器中才能进行运算的(所有的高级语言层面抽象出来的数据结构和在这之上的操作,最终都要基于最底层硬件的寄存器、指令等来表现,中间转化过程一般有编译器完成),而寄存器是没有有符号和无符号的属性的,32位cpu上的寄存器由32个二进制位组成,至于其中放的是有符号数还是无符号数,则要看你怎么用它,就如一棵树,你可以把它做成家具,也可以把它当成柴火,要看你的需求。比如我们要将4位的整数1011扩展为8位的整数,如果我们(其实是编译器的工作)认为它是无符号的数,那么可以使用零扩展转移指令,变为00001011;如果认为是有符号,可以使用符号扩展转移指令,变为11111011(补码表示)。如果我们任性的要把4位的有符号的数变为8位无符号的数,也可以,但是要制定统一的规则,比如C标准中有该规定,那么这种转化就是可移植的,如果没有统一的规则,每个编译器都有自己的搞法,这件事就变成了依赖于编译器的事情,这就是所谓的依赖性。所谓的可移植性就是有统一的标准,所谓的不可移植,即依赖性,就是因为大家各搞各的。


参考CSAPP和C99


推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
author-avatar
yangweizhi62057
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有