这里以signed/unsigned char, signed/unsigned short, signed/unsigned int类型为例,

讨论一下基本类型转换的基本原理,这样我们在编程中碰到由类型错误转换而引发的越界问题时,也可以比较容易诊断,不至于把BUG怀疑到机器或编译器身上:)。

本文属于个人原创,任何个人都可以转载,但请务必提供转载地址。

一,3种基本类型表示范围如下 (圆形示例图),其中阴影部分的弧边界包含的是没有越界的数值范围:

2,类型转换原则小结:

我们把类型转换分成两类:

1)同类型符号之间的转换:

  *同长度类型,不做转换,如int->int,

  *向更长度类型转换,如char->short->int

  原则:向高字节对齐

       因为有足够位数容纳数值,所以数值会保持不变;

     若为负数时高位会被1,若为正数时高位会补0.

*向短长度类型转换:如int ->short->char

原则:高字节截断,低字节保留。

2)不同类型符号之间的转换:

  *同长度类型转换:如int<->unsigned int

  原则:重新解释至目标类型,

      这里是重新解释,换名话说,在等长字节时,有符号类型和无符号类型在内存中的十六进制表示仍然是一样的。

     当数值范围溢出时,重新解释会造成前后两者数值的会发生巨大跳变,详见示例。

  *向更长类型转换:如char->unsigned int

  原则:先字节对齐,再类型统一。

     如:char->unsigned int  ===>char -> int ->unsigned int

unsigned char -> int ===>unsigned char ->unsigned int ->int

  这个原则会造成将负数执行”跨类型跨字节“转换时,前后两数值之间很大差距,

  如果想让差距变得”相对“合理些(等价于重新解释后的数值),你需要手动做强制转换:先类型统一,再做字节对齐。

  *向更短字节对齐:如int->unsigned char

  原则:高字节截断,低字节保留

提示:

  1)如果想要转换无错,还是规规矩矩的保证数值:不要溢出,不要截断,不要跨类型跨字节转换。

  2)在”有符号类型“向”无符号类型“转换时,数值不要为负数,否则打印出的数值并非你想要的结果。

  尤其是“有符号短字节类型“向”无符号长字节类型转换“时,负数会按照高字节补1的原则,你将会得到一个无敌错错值。

3,类型转换源代码

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4.  
  5. typedef char s8;
  6. typedef unsigned u8;
  7. typedef short s16;
  8. typedef unsigned short u16;
  9. typedef int s32;
  10. typedef unsigned int u32;
  11.  
  12. #define NONE "\033[0m"
  13. #define BLUE "\033[0;32m"
  14. #define RED "\033[0;31m"
  15.  
  16. void func_s8(s8 num)
  17. {
  18. s8 s8Num = num;
  19. u8 u8Num = num;
  20. s16 s16Num = num;
  21. u16 u16Num = num;
  22. s32 s32Num = num;
  23. u32 u32Num = num;
  24. //signed->signed
  25. printf(BLUE " s8[%hhd#0x%02hhx]:" NONE "\ns16(%hd#0x%04hx) \ns32(%d#0x%08x)\n",
  26. s8Num, s8Num, s16Num, s16Num, s32Num, s32Num);
  27.  
  28. //signed->unsigned
  29. printf(" u8(%hhu#0x%02hhx) \nu16(%hu#0x%04hx) \nu32(%u#0x%08x)\n",
  30. u8Num, u8Num, u16Num, u16Num, u32Num, u32Num);
  31. }
  32.  
  33. void func_u8(u8 num)
  34. {
  35. s8 s8Num = num;
  36. u8 u8Num = num;
  37. s16 s16Num = num;
  38. u16 u16Num = num;
  39. s32 s32Num = num;
  40. u32 u32Num = num;
  41. //unsigned->unsigned
  42. printf(BLUE " u8[%hhu#0x%02hhx)]" NONE "\nu16(%hu#0x%04hx) \nu32(%u#0x%08x)\n",
  43. u8Num, u8Num, u16Num, u16Num, u32Num, u32Num);
  44.  
  45. //unsigned->signed
  46. printf(" s8(%hhd#0x%02hhx): \ns16(%hd#0x%04hx) \ns32(%d#0x%08x)\n",
  47. s8Num, s8Num, s16Num, s16Num, s32Num, s32Num);
  48. }
  49.  
  50. void func_s16(s16 num)
  51. {
  52. s8 s8Num = num;
  53. u8 u8Num = num;
  54. s16 s16Num = num;
  55. u16 u16Num = num;
  56. s32 s32Num = num;
  57. u32 u32Num = num;
  58. //signed->signed
  59. printf(BLUE "s16[%hd#0x%04hx]: " NONE "\ns32(%d#0x%08x) \n s8(%hhd#0x%02hhx)\n",
  60. s16Num, s16Num, s32Num, s32Num, s8Num, s8Num);
  61.  
  62. //signed->unsigned
  63. printf("u16(%hu#0x%04hx) \nu32(%u#0x%08x) \n u8(%hhu#0x%02hhx)\n",
  64. u16Num, u16Num, u32Num, u32Num, u8Num, u8Num);
  65. }
  66.  
  67. void func_u16(u16 num)
  68. {
  69. s8 s8Num = num;
  70. u8 u8Num = num;
  71. s16 s16Num = num;
  72. u16 u16Num = num;
  73. s32 s32Num = num;
  74. u32 u32Num = num;
  75. //unsigned->unsigned
  76. printf(BLUE "u16[%hu#0x%04hx]:" NONE "\nu32(%u#0x%08x) \n u8(%hhu#0x%02hhx)\n",
  77. u16Num, u16Num, u32Num, u32Num, u8Num, u8Num);
  78.  
  79. //unsigned->signed
  80. printf("s16(%hd#0x%04hx) \ns32(%d#0x%08x) \n s8(%hhd#0x%02hhx)\n",
  81. s16Num, s16Num, s32Num, s32Num, s8Num, s8Num);
  82. }
  83.  
  84. void func_s32(s32 num)
  85. {
  86. s8 s8Num = num;
  87. u8 u8Num = num;
  88. s16 s16Num = num;
  89. u16 u16Num = num;
  90. s32 s32Num = num;
  91. u32 u32Num = num;
  92. //signed->signed
  93. printf(BLUE "s32[%d#0x%08x]:" NONE "\ns16(%hd#0x%04hx) \n s8(%hhd#0x%02hhx)\n",
  94. s32Num, s32Num, s16Num, s16Num, s8Num, s8Num);
  95.  
  96. //signed->unsigned
  97. printf("u32(%u#0x%08x) \nu16(%hu#0x%04hx) \n u8(%hhu#0x%02hhx)\n",
  98. u32Num, u32Num, u16Num, u16Num, u8Num, u8Num);
  99. }
  100.  
  101. void func_u32(u32 num)
  102. {
  103. s8 s8Num = num;
  104. u8 u8Num = num;
  105. s16 s16Num = num;
  106. u16 u16Num = num;
  107. s32 s32Num = num;
  108. u32 u32Num = num;
  109. //unsigned->unsigned
  110. printf(BLUE "u32[%u#0x%08x]" NONE "\nu16(%hu#0x%04hx) \n u8(%hhu#0x%02hhx)\n",
  111. u32Num, u32Num, u16Num, u16Num, u8Num, u8Num);
  112.  
  113. //unsigned->signed
  114. printf("s32(%d#0x%08x): \ns16(%hd#0x%04hx) \n s8(%hhd#0x%02hhx)\n",
  115. s32Num, s32Num, s16Num, s16Num, s8Num, s8Num);
  116. }
  117.  
  118. int main()
  119. {
  120. printf(RED "######s8Num testing######\n" NONE);
  121. s8 s8Num = 0x7F;
  122. func_s8(s8Num);
  123. s8Num = 0x80;
  124. func_s8(s8Num);
  125. s8Num = 0xFF;
  126. func_s8(s8Num);
  127.  
  128. printf(RED "######u8Num testing######\n"NONE);
  129. u8 u8Num = 0x7F;
  130. func_u8(u8Num);
  131. u8Num = 0x80;
  132. func_u8(u8Num);
  133. u8Num = 0xFF;
  134. func_u8(u8Num);
  135.  
  136. printf(RED "######s32Num testing######\n"NONE);
  137. s32 s32Num = 0x7FFFFFFF;
  138. func_s32(s32Num);
  139. s32Num = 0x80000000;
  140. func_s32(s32Num);
  141. s32Num = 0xFFFFFFFF;
  142. func_s32(s32Num);
  143.  
  144. printf(RED "######u32Num testing######\n"NONE);
  145. u32 u32Num = 0x7FFFFFFF;
  146. func_u32(u32Num);
  147. u32Num = 0x80000000;
  148. func_u32(u32Num);
  149. u32Num = 0xFFFFFFFF;
  150. func_u32(u32Num);
  151.  
  152. printf(RED "######s16Num testing######\n"NONE);
  153. s16 s16Num = 0x7FFF;
  154. func_s16(s16Num);
  155. s16Num = 0x8000;
  156. func_s16(s16Num);
  157. s16Num = 0xFFFF;
  158. func_s16(s16Num);
  159.  
  160. printf(RED "######u16Num testing######\n"NONE);
  161. u16 u16Num = 0x7FFF;
  162. func_u16(u16Num);
  163. u16Num = 0x8000;
  164. func_u16(u16Num);
  165. u16Num = 0xFFFF;
  166. func_u16(u16Num);
  167.  
  168. return ;
  169. }

4,类型转换运行结果

  1. ######s8Num testing######
  2. s8[127#0x7f]:
  3. s16(#0x007f)
  4. s32(#0x0000007f)
  5. u8(#0x7f)
  6. u16(#0x007f)
  7. u32(#0x0000007f)
  8. s8[-128#0x80]:
  9. s16(-#0xff80)
  10. s32(-#0xffffff80)
  11. u8(#0x80)
  12. u16(#0xff80)
  13. u32(#0xffffff80)
  14. s8[-1#0xff]:
  15. s16(-#0xffff)
  16. s32(-#0xffffffff)
  17. u8(#0xff)
  18. u16(#0xffff)
  19. u32(#0xffffffff)
  20. ######u8Num testing######
  21. u8[127#0x7f)]
  22. u16(#0x007f)
  23. u32(#0x0000007f)
  24. s8(#0x7f):
  25. s16(#0x007f)
  26. s32(#0x0000007f)
  27. u8[128#0x80)]
  28. u16(#0x0080)
  29. u32(#0x00000080)
  30. s8(-#0x80):
  31. s16(#0x0080)
  32. s32(#0x00000080)
  33. u8[255#0xff)]
  34. u16(#0x00ff)
  35. u32(#0x000000ff)
  36. s8(-#0xff):
  37. s16(#0x00ff)
  38. s32(#0x000000ff)
  39. ######s32Num testing######
  40. s32[2147483647#0x7fffffff]:
  41. s16(-#0xffff)
  42. s8(-#0xff)
  43. u32(#0x7fffffff)
  44. u16(#0xffff)
  45. u8(#0xff)
  46. s32[-2147483648#0x80000000]:
  47. s16(#0x0000)
  48. s8(#0x00)
  49. u32(#0x80000000)
  50. u16(#0x0000)
  51. u8(#0x00)
  52. s32[-1#0xffffffff]:
  53. s16(-#0xffff)
  54. s8(-#0xff)
  55. u32(#0xffffffff)
  56. u16(#0xffff)
  57. u8(#0xff)
  58. ######u32Num testing######
  59. u32[2147483647#0x7fffffff]
  60. u16(#0xffff)
  61. u8(#0xff)
  62. s32(#0x7fffffff):
  63. s16(-#0xffff)
  64. s8(-#0xff)
  65. u32[2147483648#0x80000000]
  66. u16(#0x0000)
  67. u8(#0x00)
  68. s32(-#0x80000000):
  69. s16(#0x0000)
  70. s8(#0x00)
  71. u32[4294967295#0xffffffff]
  72. u16(#0xffff)
  73. u8(#0xff)
  74. s32(-#0xffffffff):
  75. s16(-#0xffff)
  76. s8(-#0xff)
  77. ######s16Num testing######
  78. s16[32767#0x7fff]:
  79. s32(#0x00007fff)
  80. s8(-#0xff)
  81. u16(#0x7fff)
  82. u32(#0x00007fff)
  83. u8(#0xff)
  84. s16[-32768#0x8000]:
  85. s32(-#0xffff8000)
  86. s8(#0x00)
  87. u16(#0x8000)
  88. u32(#0xffff8000)
  89. u8(#0x00)
  90. s16[-1#0xffff]:
  91. s32(-#0xffffffff)
  92. s8(-#0xff)
  93. u16(#0xffff)
  94. u32(#0xffffffff)
  95. u8(#0xff)
  96. ######u16Num testing######
  97. u16[32767#0x7fff]:
  98. u32(#0x00007fff)
  99. u8(#0xff)
  100. s16(#0x7fff)
  101. s32(#0x00007fff)
  102. s8(-#0xff)
  103. u16[32768#0x8000]:
  104. u32(#0x00008000)
  105. u8(#0x00)
  106. s16(-#0x8000)
  107. s32(#0x00008000)
  108. s8(#0x00)
  109. u16[65535#0xffff]:
  110. u32(#0x0000ffff)
  111. u8(#0xff)
  112. s16(-#0xffff)
  113. s32(#0x0000ffff)
  114. s8(-#0xff)

C++中关于类型转换的问题讨论的更多相关文章

  1. java中强制类型转换

    在Java中强制类型转换分为基本数据类型和引用数据类型两种,这里我们讨论的后者,也就是引用数据类型的强制类型转换. 在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需 ...

  2. JavaScript中数据类型转换总结

    JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...

  3. JS中String类型转换Date类型 并 计算时间差

    JS中String类型转换Date类型 1.比较常用的方法,但繁琐,参考如下:主要使用Date的构造方法:Date(int year , int month , int day)<script& ...

  4. SQL中的类型转换

    SQL中的类型转换一直是以块心病,因为用得比较少,所以每次想用的时候都要想半天,恰好这段时间比较空,整理整理.今天写个标题先.

  5. Struts2中的类型转换

    1.     Struts2中的类型转换 我们知道通过HTTP提交到后台的数据,都是字符串的形式,而我们需要的数据类型当然不只字符串类型一种.所以,我们需要类型转换! 在Struts2中,类型转换的概 ...

  6. java中的类型转换

    java中的类型转换分为两种 自动类型转换 要实现数据的自动类型转换必须同时满足下面两个条件 两种数据类型彼此兼容 目标类型的取值范围大于原类型范围 强制类型转换 当两种数据类型彼此不兼容,或者说目标 ...

  7. HQL语句中数据类型转换,及hibernate中createQuery执行hql报错

    一.HQL语句中数据类型转换: 我们需要从数据库中取出序号最大的记录,想到的方法就是使用order by子句进行排序(desc倒序),然后取出第一个对象,可是当初设计数据库时(我们是在原来的数据库的基 ...

  8. Java中数据类型转换&基本类型变量和对象型变量

    1.Java的数据类型分为三大类 布尔型,字符型和数值型 其中数值型又分为整型和浮点型 2.Java的变量类型 布尔型 boolean 字符型 char 整型    byte,short,int,lo ...

  9. C语言中强制类型转换总结

    C语言中强制类型转换总结  ● 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围 ...

随机推荐

  1. C#DataGrdviewl加入checkBox全选删除

    #region 加入checkBox /// <summary> /// 加入checkBox /// </summary> /// <param name=" ...

  2. lintcode:数字组合 II

    数字组合 II 给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T.C中每个数字在每个组合中只能使用一次. 注意事项 所有的数字(包括目标数字)均为正整数. 元素组合(a ...

  3. SQLHelper.cs的经典代码-存储过程

    using System; using System.Collections.Generic; using System.Text; using System.Collections; using S ...

  4. ntelliJ IDEA 14 注册码

    user or company nameo license key63625-MQ87K-3SRZ2-8MQYB-6NQZC-2Z8K6

  5. asp.net+swfupload 多图片批量上传(附源码下载)

    asp.net的文件上传都是单个文件上传方式,无法执行一次性多张图片批量上传操作,要实现多图片批量上传需要借助于flash,通过flash选取多个图片(文件),然后再通过后端服务进行上传操作. 本次教 ...

  6. POJ3252——Round Number(组合数学)

    Round Numbers DescriptionThe cows, as you know, have no fingers or thumbs and thus are unable to pla ...

  7. Python ->> 第一个Python程序

    #coding:utf-8 #print 'input your name, please' #name = raw_input('请输入你的名字:'.decode('utf-8').encode(' ...

  8. WEB前端介绍

    1.WEB前端是神马 Web前端开发是从网页制作演变而来的,名称上有很明显的时代特征.在互联网的演化进程中,网页制作是Web1.0时代的产物,那时网站的主要内容都是静态的,用户使用网站的行为也以浏览为 ...

  9. 存根类STUB

    当我们创建一个指定各种方法集合的接口时,我们可以考虑使用"存根”STUB,“存根”就是用空方法体实现该接口中所有方法的类,这样我们就可以通过继承该“存根”创建一个实现该接口的类,这样一来,该 ...

  10. ArcGIS Engine中的8种数据访问

    数据是GIS的基础, 访问数据也是进行任何复杂的空间分析及空间可视化表达的前提.ArcGIS支持的数据格式比较丰富,对不同的数据格式支持的程度也有很大差异.本文主要介绍一下以下八种数据格式在ArcGI ...