在 C++ 中,当我声明一个整数变量 int a = 200L 或 int a = 200F 或 int a = 200U 时,它允许。这是怎么发生的?
Posted
技术标签:
【中文标题】在 C++ 中,当我声明一个整数变量 int a = 200L 或 int a = 200F 或 int a = 200U 时,它允许。这是怎么发生的?【英文标题】:in c++ when i declare an integer variable int a = 200L or int a = 200F or int a = 200U, It allows. How does this happen? 【发布时间】:2018-08-27 15:07:26 【问题描述】:基本上,整数变量应该只允许为其变量设置整数值。那怎么会允许下面这种特殊的词呢?
int a = 200L;
int a = 200U;
int a = 200F;
我在运行程序时发现了这一点,它运行完美,没有出现任何错误。其他字母按预期不允许。但为什么是这些?
【问题讨论】:
在尝试运行一些代码之前,请先获得一本教科书。这太基础了。 其实我是编程新手。 这正是您应该从一本好书开始的原因。 ***.com/questions/388242/… 好的。但是你能告诉我答案吗? U L F : 整数后缀en.cppreference.com/w/cpp/language/integer_literal 【参考方案1】:L、U 和 F 分别表示 long、unsigned 和 float。 所以,代码意味着
int a = (long) 200;
int a = (unsigned) 200;
int a = (float) 200;
【讨论】:
问题是为什么允许初始化,而不是常量有什么类型。 没错!!最后变量 a 的数据类型是什么?右边是“int”还是“long/unsigned/float”?【参考方案2】:你所做的就是隐式转换。
如果你使用 gcc 编译器,你可以添加
-Wconversion
(不是 -Wall 的一部分)选项来检查任何可能改变值的隐式转换。 如果没有任何选项,默认情况下不会警告从有符号到无符号的转换。所以你需要主动
-Wsign-conversion
如果您想要显式转换,这两个选项不会警告它。
int percent = (int)((int)4.1)*.5;
【讨论】:
【参考方案3】:这里发生了两种不同的事情。
1) 一些字母在数字末尾时具有意义。 'l' 代表 long,'u' 代表 unsigned,而 'f' 代表 float。
“Long”通常是 64 位宽,而 int 是 32 位...但这可以 机器之间差异很大。不要依赖于位宽 整数和长。 “未签名”表示它不会费心跟踪阳性或 负值...假设一切都是积极的。这关于 双倍整数可以走多高。查找“二的补码”为 更多信息。 “浮点”表示“浮点”。非整数。 1.5、3.1415 等。它们可以非常大,也可以非常精确,但不能两者兼而有之。浮点数是 32 位。 “Double”是一个 64 位浮点值,它可以允许一些极端的大小或精度值。2) 强制类型,发音为“co ER shun”。
编译器知道如何将 long 转换为 int、unsigned 转换为 int 或 float 转换为 int。他们都只是数字,对吧?请注意,从浮点数转换为“截断”(删除)小数点后的任何内容。 ((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
这是三层强制。 double 到 int, into 到 foo, foo 到 corge。呸!
您可以使用 explicit
关键字阻止此操作:
struct Foo
explicit Foo(int bar) ...
;
Foo baz = 1; // won't compile
我希望他们将 explicit
设为默认值并使用一些关键字来定义转换构造函数,但这种更改几乎肯定会破坏某人的代码,所以它永远不会发生。
【讨论】:
【参考方案4】:发生的情况是您告诉编译器将值转换为不同类型的数据。也就是说:
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
没有错误,因为编译器知道这些字母末尾表示一种转换。
【讨论】:
以上是关于在 C++ 中,当我声明一个整数变量 int a = 200L 或 int a = 200F 或 int a = 200U 时,它允许。这是怎么发生的?的主要内容,如果未能解决你的问题,请参考以下文章