c语言的概念,在c语言中,整数有三种表达形式

  c语言的概念,在c语言中,整数有三种表达形式

  C的本质(3)——整数的本质和运算

  计算机存储的最小单位是字节,一个字节通常是8位。c语言规定char类型占用一个字节的存储空间。如果这8位被解释为无符号整数,则取值范围为0到255,如果被解释为有符号整数,则取值范围为-128到127。c指定了两个关键字:有符号和无符号。无符号字符类型表示无符号数,有符号字符类型表示有符号数。

  对于char的类型,编译器可以定义char的类型是无符号的还是有符号的。在与编译器相对应的架构中,可以采用任何高效的实现。x86平台的gcc定义char是有符号的。

  这是C标准的规则之一:效率优先,可移植性次之。这就需要程序员非常清楚这些规则。如果你想写可移植的代码,你必须知道哪些编写方法是不可移植的,应该避免使用。另一方面,有时需要编写不可移植的代码。例如,Linux内核代码使用了大量gcc特性来获得最佳的执行效率。写的时候不打算被其他编译器编译,所以不考虑可移植性。如果要写不可移植的代码,还必须知道代码的哪些部分是不可移植的,以及为什么要这样写。如果不是为了效率,一般没有理由刻意去写不可移植的代码。

  c语言与平台和编译器密切相关。如果离开具体的平台和编译器来讨论C语言,只能讨论到本书的第一部分。注意ASCII码的取值范围是0~127,所以不管char类型是有符号还是无符号,存储一个ASCII码都没有问题。一般来说,如果使用char类型存储ASCII码字符,就不必显式地写有符号或无符号。如果char type用作8位整数,则为了便于移植,必须指定它是有符号的还是无符号的。

  ANSI C99标准中定义了两种类型(四种类型)的修饰符:长/短和无符号/有符号。

  C99标准规定长型不能短于柔性型,短型不能长于普通型。但是,无符号和有符号的区别在于实现中有没有符号,而在于使用中取值范围的区别。两者都表示相同的范围,但前者都是正数,后者是关于0对称的。

  描述:

  Long/short可以修改int,Long也可以修改double。

  Unsigned/signed可以修饰int,char,但不能修饰浮点。

  int的长度是机器的字长,短int是字长的一半,长int是一两个字长。

  unsigned/signed的长度与normal类型的长度相同,只是间隔不同。

  各种整数数据类型的表示和值范围:

  整数

  [签名]int

  -2147483648~ 2147483648

  无符号的

  无符号[int]

  0~4294967295

  短整数

  短[int]

  -32768~32768

  无符号短整数

  无符号短整型[int]

  0~65535

  长整数

  长整型

  -2147483648~ 2147483648

  无符号长整数

  无符号[int]

  0~4294967295

  性格;角色;字母

  [签名]字符

  -128~ 127

  无符号字符类型

  无符号字符

  0~255

  既然知道了正整数的表示方法,知道了计算机中加法的计算方法,那么负数的表示方法呢?减法怎么算?为了书写方便,下面所有的例子都用8位来表示一个数。实际计算机算术运算的操作数可以是8位、16位、32位甚至64位。

  要用8位来表示正数和负数,一个简单的思路就是把最高位看成一个符号位,0代表正1代表负,剩下的7位代表绝对值。例如,-1表示为1000001,1表示为0000001。

  要将这两个数字相加,计算机需要处理以下逻辑:

  1.如果两个数的符号位相同,则将它们的低7位相加,符号位保持不变。如果低7位相加时在最高位产生进位,结果超过7位所能表示的数值范围,称为溢出。通常,计算机中的标志位置1表示溢出。

  2.如果两个数的符号位不同,先比较它们的低7位,然后用大的数减。结果的符号位与大数相同。

  减法需要以下逻辑:

  1.如果两个数的符号位相同,且低7位为大数的缩减数,则符号位保持不变;如果低7位是小数的缩减数,则按照大数的缩减数计算,结果会有变化。

  2.如果两个数的符号位不同,则将低7位相加。如果是正数,结果就为正;如果是负数减去正数,结果就是负数。添加时,低7位可能溢出。

  其实这和手工加减法的逻辑是一样的。加减需要处理这么多逻辑:比较符号位,比较绝对值,变加为减,变减为加,变小数为大数减.这是非常低效的。另一个缺点是0的表示不是唯一的。既可以表示为1000000,也可以表示为000000,进一步增加了逻辑的复杂度。因此,我们迫切需要重新设计数字的表示方式,使计算过程更加简单。

  有一种方法是把所有的减法都转换成加法来计算,这样就不需要设计加法器和减法器两个电路。让我们以十进制减法为例来理解这个方法。例如:

  167-52=167 (999-52)-1000 1=167 947-1000 1=1114-1000 1=114 1=115

  先把52换成999-52,也就是947,叫做9的补数。虽然这也是减法,但是不需要借位,只需要对每一位取补数,所以比一般的减法简单很多。然后将167和947相加,丢弃百位中的进位,得到114,再加1得到115[21]。这是最后的结果。总之,减去一个数等于加上它的补数9,再加上1(忽略最高阶进位)。

  这种方法也可以类比为二进制加减法:减去一个数等于加上这个数的1的补码再加1(忽略MSB的进位)。1的补码是1-1=0,1-0=1,实际上相当于把每个数字反相。在将来,1的补码将简称为逆码。例如

  00001000-00000100- 00001000 11111011 1- 00000011 1=00000100

  formula的前两步不是等价变换,所以用-代替=符号表示。第一步多加了10000000,第二步多加了10000000,效果互相抵消,所以最后的结果正好是00001000-0000100的结果。现在我们发现,如果第一步写成00001000(-0000100)-00001001111011 1,那么11111011 1可以用来表示负数-00000100。因此,补码表示法不仅可以将减法转化为加法,而且可以合理地规定负数的表示方法,即“先取反码再加1”。负数的这种表示被称为2的补数,简称为补数。为什么叫二进制补码?因为如果取一个数字的补码,1的补码就是1-1 1=10-1=1,相当于2减1。同样,00000100的补码是111111-00000100 1=1000000-0000100,相当于100000000减去0000100(十进制256)。

  所有负数用补码表示后,8位表示的正数是0000000 ~ 0111111(十进制0~127),负数是1000000 ~ 111111(十进制-128~-1),总共都是十进制-128~127。我们还发现所有正数的最高位都是0,所有负数的最高位都是1,所以最高位还是有符号位的意思。要检查一个数是否为负,只需查看最高位。但是,在计算中,您可以将符号位和数字放在一起进行加法运算,而不必像符号和幅度符号那样单独处理符号位。

  当补码用于加法和减法时,MSB的进位总是被忽略。如果忽略进位的影响在计算过程中没有相互抵消,最后的结果肯定是错的,一定是溢出造成的。只要我们有办法判断哪些情况会导致溢出,其他情况下就可以放心地忽略MSB的进位。判断溢出的方法如下:如果最高位产生的进位和次高位产生的进位相同,则没有溢出;否则就意味着溢出。逻辑电路的实现可以将这两个进位连接到异或门,并将异或门的输出连接到溢出标志位。对于8位二进制数的加减运算,当计算结果超出-128~127的范围时会溢出,例如:

  有符号数加法溢出

  最高位产生的进位为1,次高位产生的进位为0,表示溢出。计算结果换算成十进制122,显然是错误的。根本原因是(-126) (-8)=-134超出了8位二进制数所能表示的范围。

  如果用8位同时表示正数和负数,则表示范围为-128~127。如果8位都是正数,表示的范围是0~255。前者称为有符号数,后者称为无符号数。但计算机在加法时并不区分操作数是有符号数还是无符号数,计算过程是一样的,所以上面的例子也可以看作是无符号数加法:

  无符号数加法进位

  将两个操作数分别视为无符号数130和248是正确的,换算成十进制时计算结果为122,最高阶进位相当于256,122,256。计算机加法器完成计算后,根据最高位产生的进位设置进位标志,根据最高位和次高位产生的进位的异或设置溢出标志。至于这个加法是有符号的还是无符号的,就看程序怎么理解了。如果程序认为它是有符号加法,检查溢出标志。如果程序认为它是无符号加法,检查进位标志。通常,计算机可能在算术运算后设置另外两个标志。如果结果为零,则置零标志,如果结果的最高位为1,则置负标志(该标志只有在理解为有符号数运算时才会被检查)。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • c语言调用退出函数 c语言退出整个程序怎么写
  • c语言中怎么给函数初始化 c语言的初始化语句
  • c语言编写函数计算平均值 c语言求平均函数
  • 详解c语言中的字符串数组是什么,详解c语言中的字符串数组结构,详解C语言中的字符串数组
  • 表达式求值c++实现,c语言实现表达式求值
  • 看懂c语言基本语法,C语言详解,C语言的基本语法详解
  • 用c语言实现快速排序算法,排序算法设计与实现快速排序C语言,C语言实现快速排序算法实例
  • 深入解析c语言中函数指针的定义与使用方法,深入解析c语言中函数指针的定义与使用情况,深入解析C语言中函数指针的定义与使用
  • 描述E-R图,E-R图举例,关于C语言中E-R图的详解
  • 折半查找法C语言,折半查找算法(算法设计题)
  • 折半查找法C语言,c语言折半法查找数据,C语言实现折半查找法(二分法)
  • 扫雷小游戏c++代码设计,c语言扫雷游戏源代码,C语言实现扫雷小游戏详细代码
  • 怎样统计程序代码行数,C语言统计行数,C#程序员统计自己的代码行数
  • 基于c语言的贪吃蛇游戏程序设计,用c语言编写贪吃蛇游戏程序,C语言实现简单的贪吃蛇游戏
  • 图的两种遍历算法,图的遍历算法代码c语言,Python算法之图的遍历
  • 留言与评论(共有 条评论)
       
    验证码: