#AB05. 挂分经典错误1
挂分经典错误1
当前没有测试数据。
1. 函数该返回时不返回
非 void
类型函数,如果没有返回对应类型的值,DevC++ 可以正常运行,但是 OJ 和比赛评测环境都会直接爆零。
2. 精度不够的 double
众所周知,比赛环境中 double
类型占 个字节,和 long long
一样。所以显然无法精确储存 long long
范围的所有数。
而有很多表达式因为是 double
,常常导致精度损失而丢失分数:
- •
1e18+1
:转成long long
后值会是 - •
0.1+0.2
:值会是0.30000000000000004
,所以0.1 + 0.2 != 0.3
- •
sqrt()
:默认返回值是double
- •
pow()
:默认返回值是double
- •
log2()
:默认返回值是double
3. 窄化转换
下面这段代码展现了一些爆 惨剧。
#include<bits/stdc++.h>
using namespace std;
struct Num{
int x;
};
Num a;
int main(){
a = {1e18};
cout<<"Hello World";
return 0;
}
这个代码可以在 DevC++ 中成功运行(伴随着一些警告),但是会在正式比赛中直接得到编译错误。这是因为大括号初始化不允许窄化转换,绝大多数版本的编译器下都会得到编译错误,而在某些编译器版本下(比如 DevC++ 的 4.9.2 版本)中只会警告。
窄化转换
在C++中,窄化转换(narrowing conversion)是一种潜在的不安全的数值转换,其中目标类型可能无法保存源类型的所有值。
以下转换被定义为窄化转换:
- • 从浮点类型到整型。
- • 从浮点类型到级别较窄或较低的浮点类型,除非要转换的值是constexpr并且在目标类型的范围内(即使目标类型的精度不足以存储数字的所有有效数字)。
- • 从整数类型转换为浮点类型,除非要转换的值是constexpr,并且其值可以精确存储在目标类型中。
- • 从整型转换为不能表示原始类型的所有值的另一整型,除非要转换的值是constexpr,并且其值可以精确存储在目标类型中。这包括从宽到窄的整数转换,以及整数符号转换(有符号到无符号,反之亦然)。
- • 在大多数情况下,隐式窄化转换将导致编译器警告,但有符号/无符号转换除外(根据编译器的配置方式,这可能会产生警告,也可能不会产生警告)。
应尽可能避免窄化转换,因为它们可能不安全,是潜在错误的来源。
大括号初始化不允许窄化转换,除少数几个版本的编译器外,都会得到编译错误。