>基本上,整数变量应该只允许为其变量设置整数值。那为什么允许这样特殊的话呢?
int a = 200L;
int a = 200U;
int a = 200F;
我在运行程序时发现了这一点,它运行完美,没有任何错误。其他字母不允许按预期进行。但为什么是这些呢?
L,U和F分别表示长,无符号和浮点数。
所以,代码意味着
int a = (long) 200;
int a = (unsigned) 200;
int a = (float) 200;
你所做的称为隐式转换。
如果您使用的是 gcc 编译器,您可以添加
-Wconversion
(不是 -Wall 的一部分)选项来检查任何可能更改值的隐式转换。 如果没有任何选项,默认情况下不会警告从已签名到未签名的转换。所以你需要活跃
-Wsign-conversion
如果您想要显式转换,则不会受到这两个选项的警告。
int percent = (int)((int)4.1)*.5;
这里发生了两件不同的事情。
1)一些字母卡在数字的末尾时具有意义。 "l"代表长,"u"代表无符号,"f"代表浮点数。
- "长"通常为 64 位宽,而 int 的宽度为 32 位......但那可以 因机器而异。 不依赖于位宽 内和长。
- "未签名"意味着它不会费心跟踪正面或 负值...假设一切都是积极的。 这关于 整数可以加倍。 查找"二的补码" 更多信息。 "浮
- 点"的意思是"浮点"。 非整数。 1.5、3.1415 等 它们可以非常大,也可以非常精确,但不能两者兼而有之。 浮点数为 32 位。 "Double"是一个 64 位浮点值,它可以允许一些大小或精度的极值。
2)类型胁迫,发音为"co ER shun"。
编译器知道如何将 long 转换为 int、从 unsigned 转换 (强制) 到 int,或从 float 转换到 int。 它们都只是数字,对吧? 请注意,从浮点数转换为"truncates"(删除)小数位后的任何内容。((int)3.00000001) == 3
.((int)2.9999999) == 2
如果您将警告调到最大灵敏度,我相信这些语句都会触发警告,因为所有这些转换都可能会丢失数据......尽管该警告的确切措辞因编译器而异。
奖金信息:
您可以使用类(意外)触发相同的行为。
struct Foo {
Foo(int bar) {...}
};
Foo baz = 42;
编译器在寻求从 int 转换为 Foo 时会将上述构造函数视为一个选项。 编译器愿意跳过多个箍来到达那里......所以Foo qux = 3.14159;
也会编译。 其他类构造函数也是如此...因此,如果您有其他一些类将 Foo 作为它只是构造函数参数,您可以声明该类的变量并为其分配可以强制分配给 foo 的东西......等等:
struct Corge {
Corge(Foo foo) {...}
};
corge grault = 1.2345; // you almost certainly didn't intend what will happen here
这是三层胁迫。 双倍到int,成Foo,Foo到Corge。 嘭! 您可以使用explicit
关键字阻止此操作:
struct Foo {
explicit Foo(int bar) {...}
};
Foo baz = 1; // won't compile
我希望他们explicit
默认设置并使用一些关键字来定义转换构造函数,但这种更改几乎肯定会破坏某人的代码,所以它永远不会发生。
发生的情况是,您告诉编译器将值转换为不同类型的数据。也就是说:
int a = 200L; // It's like saying: Hey C++, convert this whole to Long
int a = 200U; // And this to Unsigned
int a = 200F; // And this one to Float
没有错误,因为编译器知道末尾的这些字母表示一种转换类型。