- 2.6.1.隐式类型转换
- 2.6.2.算术类型转换
- 2.6.3.显式类型转换
2.6.1.隐式类型转换
如果在源代码中的某个位置使用了一种类型,但需要的是另一种类型,并且两者之间存在转换规则,那么会自动进行类型转换。这种转换称为隐式类型转换,但不一定符合程序员的意图。此外,一些转换操作有副作用,编译器不知道这些转换的使用是否是有意为之,因此会用警告突出显示相应的代码行。为了解决这些问题,提供了显式类型转换语法(参见 显式类型强制转换)。
在研究类型和变量时,我们已经发现了隐式类型转换的几个规则。
具体来说,如果一个非布尔类型的值被赋给一个 bool 变量,那么 0 值被认为 false,其余被认为 true。在更常见的情况下,所有假设存在逻辑条件的表达式都被转换为 bool 类型。例如,三元条件运算符的第一个操作数总是被转换为 bool。
但是,如果将一个 bool 类型的值赋给数字类型,那么 true 变为 1,false 变为 0。
将实数赋给整数类型变量时,小数部分被丢弃(编译器会发出警告)。另一方面,当整数被赋给实数类型变量时,精度可能会丢失(编译器发出警告)。我们已经在 整数 和 实数相关章节中讨论了这些内容。
如果我们有整数和浮点数,那么都被转换为最大长度的浮点数(通常是 double,,除非你显式指定 float 或者数字字面量有后缀 f,例如 1234.56789f)。
对于不同大小的整数,也有转换规则:如果需要,它们会扩展,这意味着它们会增大到表达式中使用的最大整数类型的大小(参见 算术类型转换)。
除了表达式,当 = 符号左右两边的类型不匹配时,我们经常需要在初始化和赋值期间隐式转换类型。通过函数参数传递值以及从函数返回结果时,相同的转换规则也适用(更多详细信息,请参见 函数 一节)。
综上所述,一行代码可以执行大量转换。如果这导致编译器警告,最好确保转换是有意为之,并通过插入显式类型转换来消除警告。
short s = 10;
|
在本例中,执行乘法时,s 变量的类型被扩展到第二操作数 long 的类型,并且获得 long 类型的中间结果。因为常数 1.0 是 double 型,所以乘积的结果在执行加法之前被转换为 double。总结果也是 double 型;而变量 p 是 int 型,因此执行从 double 到 int 的隐式转换。
特殊类型 datetime 和 color 根据长度分别为 8 字节和 4 字节的整数之规则进行转换。但对于日期和时间,最大值有更严格的限制 - 32535244799,对应 D'3000.12.31 23:59:59’。
大多数类型都可以与字符串隐式相互转换,但结果并不总是令人满意,因此编译器发出警告“从‘数字’到‘字符串’的隐式转换”和“从‘字符串’到‘数字’的隐式转换”,以便程序员可以检查它们。例如,如果将字符串转换为整数,则字符串开头仅允许包含数字和 +/- 字符。从字符串转换为实数时,除了数字之外,还允许出现点号 . 以及表示“指数”的符号(e 或 E,例如 +1.2345e-1)。如果字符串中遇到不支持的字符(例如字母),则字符串的其余部分将被全部丢弃。
例如,字符串日期和时间 ("2021.12.12 00:00") 不能无损地赋给 datetime 类型的变量,因为 datetime 是一个整数(秒数)。在这种情况下,从字符串中读取数字将在到达第一个点号时结束,即获得 2021 的数字值。该秒数对应于 1970 年的第 34 分钟。
还有一些特殊的函数用于这种转换(参见 数据转换一节)。
唯一禁止的隐式和显式类型转换方向是从 string 转换为 bool。在这种情况下,编译器会显示错误消息“无法将‘string’类型隐式转换为‘bool’类型”。
本章的例子可在 TypeConversion.mq5 中找到。