看了一篇博文,该文章中有如下描述

 1 #include <stdio.h>
 2
 3 int main()
 4 {
 5     unsigned short a = 1;
 6     unsigned short b = 0;
 7
 8     if (a < (b-1)) //a和b-1的结果-1都被转换为int类型进行比较,1<-1,显然false
 9     {
10         printf("in if\n");
11     }
12
13     return 0;
14
15 }  

预期结果时打印“in if”,但实际运行时却发现啥都没有输出。改为如下代码就可以正常输出“in if”,此时与预期相符

 1 #include <stdio.h>
 2
 3 int main()
 4 {
 5     unsigned short a = 1;
 6     unsigned int b = 0;
 7
 8     if (a < (b-1)) //b-1的结果-1,被转换为0xffffffff,1<0xffffffff,显然true啊
 9     {
10         printf("in if\n");
11     }
12
13     return 0;
14
15 }  

使用汇编,直接对比两者结果(公司安全不让发送外网图片..),发现主要差异在如下5行,前四行中对short进行了扩展,由2字节扩展为4字节,高位填充0。导致运行结果与与预期不符合的原因就在第5行:jge 8048461

 1 08048425 <main>:
 2  8048425:      8d 4c 24 04              lea    0x4(%esp),%ecx
 3  8048429:      83 e4 f0                 and    $0xfffffff0,%esp
 4  804842c:      ff 71 fc                 pushl  -0x4(%ecx)
 5  804842f:      55                       push   %ebp
 6  8048430:      89 e5                    mov    %esp,%ebp
 7  8048432:      51                       push   %ecx
 8  8048433:      83 ec 14                 sub    $0x14,%esp
 9  8048436:      66 c7 45 f6 01 00        movw   $0x1,-0xa(%ebp)
10  804843c:      66 c7 45 f4 00 00        movw   $0x0,-0xc(%ebp)
11  8048442:      0f b7 45 f6              movzwl -0xa(%ebp),%eax
12  8048446:      0f b7 55 f4              movzwl -0xc(%ebp),%edx
13  804844a:      83 ea 01                 sub    $0x1,%edx
14  804844d:      39 d0                    cmp    %edx,%eax
15  804844f:      7d 10                    jge    8048461 <main+0x3c>
16  8048451:      83 ec 0c                 sub    $0xc,%esp
17  8048454:      68 00 85 04 08           push   $0x8048500
18  8048459:      e8 a2 fe ff ff           call   8048300 <puts@plt>
19  804845e:      83 c4 10                 add    $0x10,%esp
20  8048461:      b8 00 00 00 00           mov    $0x0,%eax
21  8048466:      8b 4d fc                 mov    -0x4(%ebp),%ecx
22  8048469:      c9                       leave
23  804846a:      8d 61 fc                 lea    -0x4(%ecx),%esp
24  804846d:      c3                       ret
25  804846e:      66 90                    xchg   %ax,%ax

汇编中的数值是没有符号之分的,但指令是有符号分别的,上述使用的jge即是有符号比较的方式,导致比较结果为:if (1<-1),为false,不会打印字符串

指令 含义 运算符号
jbe unsigned below or equal (lower or same) <=
jae unsigned above or equal (higher or same) >=
jb unsigned below (lower) <
ja unsigned above (higher) >
jle signed less or equal <=
jge signed greater or equal >=
jl signed less than <
jg signed greater than >

转载于:https://www.cnblogs.com/charlieroro/p/8610817.html

C语言的隐式类型转换相关推荐

  1. c语言float转换为int_C语言的隐式类型转换和显示类型转换

    C语言是一种强类型语言,当使用一种类型的对象代替另外一种类型的对象进行操作时,必须首先进行类型转换. 类型转换的方式,一般可分为隐式类型转换和显示类型转换(也称为强制类型转换). 1.隐式类型转换 隐 ...

  2. C语言----表达式求值之隐式类型转换

    前言: 表达式求值的顺序一部分是由操作符的优先级和结合性决定. 同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型,称为隐式类型转换,下面给出隐式类型转换的详细讲解,希望对大家有所帮助~ 隐 ...

  3. C语言操作符详解 隐式类型转换 (整型提升 算数转换)

    目录 一.算术操作符 二.左移操作符 右移操作符 1.二进制序列 2.左移操作符 3.右移操作符 3.1.逻辑运算/算术运算 3.2.对于移位运算符,不要移动负数位,这是标准未定义的 3.3.对于移位 ...

  4. float 与 double、隐式类型转换、switch、重写与重载、Java 与 C++ 的区别、JRE or JDK

    1.float 与 double 1.1 字面量属于 double 类型,不能直接将 1.1 直接赋值给 float 变量,因为这是向下转型. // float f = 1.1; Java 不能隐式执 ...

  5. JavaScript隐式类型转换

    JavaScript隐式类型转换 基本数据类型 ECMAScript 一共定义了七种 build-in types,其中六种为 Primitive Value,Null, Undefined,Stri ...

  6. 详解 C++ 的隐式类型转换与函数重载!

    作者 | 樱雨楼 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 在上篇中,我们讨论了C++中与隐式类型转换相关的一些话题,而函数重载是与隐式类型转换相关的又一大重要话题,本篇将要讨论的 ...

  7. 关于显式类型转换以及隐式类型转换

    哈喽嗷,铁汁们,咱们又见面了.是我嗷,一个不正经楼主. 首先提出一点,关于这个小细节专栏,看了绝对没好处(滑稽) 咳咳,咱们言归正传. 目录 隐式类型转换 ①算术运算中的隐式转换 规则一:字符和整数的 ...

  8. (基础)JavaScript类型转换(强制类型转换+隐式类型转换)

    JavaScript  中有五种基本数据类型(其中包括 String.Number.Boolean.Function.Symbol).三种对象类型(其中包括 Object.Date.Array)和两种 ...

  9. oracle c op,ORACLE中内部函数SYS_OP_C2C和隐式类型转换

    什么是SYS_OP_C2C呢?官方的介绍如下: SYS_OP_C2C is an internal function which does an implicit conversion of varc ...

  10. 没有学不会的C++:用户自定义的隐式类型转换

    C++ 中的类型转换包含内建类型的转换和用户自定义类型的转换,而这两者都又可分为隐式转换和显示转换,所以一共有如下四象限表格中的 A.B.C.D 四种情况 隐式转换 显示转换 (casting) 内建 ...

最新文章

  1. Go 学习笔记(11)— 切片定义、切片初始化、数组和切片差异、字符串和切片转换、len()、cap()、空 nil 切片、append()、copy() 函数、删除切片元素
  2. 3.6 判断两个链表是否相交
  3. 9076什么意思_9076西南大学人力资源开发与管理答案
  4. ViewConfiguration.getScaledTouchSlop () 用法
  5. JavaScript巧用对象的引用解决三级联动
  6. CodeForces - 1562E Rescue Niwen!(dp)
  7. spark1.3.1使用基础教程
  8. migrate和syncdb的区别(转载)
  9. 有前途的程序员的14个习惯,你有几个?
  10. android l 电池,DIY新技能--M1L换电池
  11. 【HTML】中国天气天气插件调用
  12. 关于程序、进程和线程
  13. SQLServer 2008 技术内幕——T-SQL 查询 笔记
  14. [转载] C#面向对象设计模式纵横谈——1. 面向对象设计模式与原则
  15. J2EE的13个规范之(三) Servlet简单介绍
  16. 全球首列氢燃料混合动力有轨电车成功商业运营,全程“无网”运行
  17. php 事件流转,php46公文流转
  18. Linux下php导出excel失败且浏览器报错500
  19. win7无法连接打印机拒绝访问_win7添加打印机提示windows无法连接到打印机怎么解决...
  20. flash 火狐总是崩溃_火狐浏览器Adobe Flash崩溃怎么办?最终解决方法

热门文章

  1. DiskGenius无损调整分区大小
  2. postgresql表空间迁移
  3. dialogfield
  4. linux内核开发常用站点
  5. DPDK之KNI原理
  6. 使用OpenCV4Android打开相机
  7. SPI以及UART的测试DEMO
  8. linux下sqlite3的使用
  9. SO_REUSEADDR 套接字选项应用实例
  10. A - 饭卡(动态规划 01背包)