语言/CPP {CPP错误汇总}

语言/CPP {CPP错误汇总}
@LOC: 2

汇总

三元运算符b ? "aa" : 3 这是错误的, 因为"aa" 和 3的类型不同;

未初始化所導致的錯誤

當發生很詭異/莫名其妙的錯誤時, 大概率是因為有變量沒有初始化的緣故;
比如對於一個函數, 控制的變量 是完全相同的 反而得到了不同的結果, 大概率是沒有初始化, 比如void F(){ int i; ...} 第一次調用函數 一般此時i==0 (會得到預期答案), 但第二次以後i就是隨機值;

&,^,|运算符的优先级 小于==

if( edge^1 == _faEdge)这是错误的, 他等价于if( edge ^ (1==_faEdge);
运算符优先级: ==等于 > > > & ^ |位运算 > > > && ||逻辑

下標越界是合法的…

@MARK: @LOC_1;

@LINK: https://www.acwing.com/problem/content/submission/code_detail/28370736/;
此时报错说是在Query函数里的报警;
如果你把163行的ASSERT_( __NodesCount < __NodesMaximum_); 放到160行, 即放到if的前面, 那么会报错会变成 你160行的这Insert函数里的;

而这一前一后 有什么区别吗? 按理说完全没问题; 這就非常玄學???

難道是因為(CPU的指令序順序的調整)? 但是即便順序調整 你的這個ASSERT報警 是一定會執行的 不會消失的呀;

其實 你仔細思考一下, 你這一前一後 區別在哪? 就完全在於 多執行了一個 你中间的那个if; (從現象來看 你肯定是修改了NodesCount這個變量 一定是的 否則這一前一後本質是完全相同的, 即本來NodesCount == NodesMaximum 可以 你修改成了比如NodesCount = -1);
__Nodes[ __NodesCount] = ?, 可是此時已經下標越界了 那麼 這個?是賦值了給誰呢? 給到了(下一個內存位置), 此時我們看你的變量定義:

int __Nodes[ __NodesCount];
int __NodesCount;

因此 實際上 你執行了NodesCount = ?, 即你修改了他;

可以證明一下 即把他倆互換位置 即讓NodesCountNodes的前面, 你會發現 一切正常了;

@DELI;

把問題簡化一下 即:

int A[10];
int Ind;

Ind = 10;
if( true){
	A[ind] = -1; // 等價於是`Ind = -1`;
}
ASSERT_( ind < 10);
A[ind] = 55;

因此, 不要下標越界, 即 你的ASSERT_( ind < 10) 要寫在if的前面;

remove_rv< T>是错误的

比如

两个类之间相互调用

MARK: @LOC_0;

class A{
	void FA( B _b){ ...}
}
class B{
	void FB( A _a){ ...}
}

此时FA会报错, 因为他找不到B这个类的定义;
1: 你需要在class A{的上一行 写成class B;声明;
. 但是 此时仍然是错误的, 因为你访问_b.xxx 这个xxx是找不到的, 因为上面只有class B;这个声明 而他里面具体的定义是找不到的;

因此, 正确做法是:

class B;
class A{
	void FA( B);
}
class B{
	void FB( A _a){ ...}
}

void A::FA( B _b){ ...}

T &const T &传参的区别 不只是修改

F( T &), FF( const T &)
你可能认为: F可以修改, FF不可以修改, 这就一点区别;
其实不是的, 还有个非常重要 且容易忽略的性质: const &还可以接收临时变量(即右值), 比如说 你的参数是个右值 那么F函数一定会报错 而FF函数是没问题的;

容器一旦修改 当前迭代器就失效了

for( const auto & i : mp){
	ANS += mp[x]; // `x`可能不存在
}

这是错误的, 如果x这个键是不存在的 则你是在添加新元素! 那么你当前所循环的迭代器就失效了 这是非常严重的错误, 你迭代器加const也不行 因为const只是表示对迭代器不可以修改 但是此时你容器已经改变了 迭代器已经失效了!
. 比如 [1,2], 第一次遍历到1 使用了3 也就是插入了3, 那么下一个遍历 可能就不是2 (也可能不是3) 也可能就直接循环结束了 (也就是, 并不会正常的遍历);

所以, 不要以为只是增加时间复杂度的问题, 而是程序出错的问题;
比如, 已知所有的mp[?] > 0, 那么你可能认为 我们即便使用不存在的键 无非就是把他设置了mp[x] = 0 并不会影响答案, 只是增加了复杂度而已;
. 确实不会影响答案, 但是 你的遍历就乱套了 整个过程并不是你想象的那样 (容器一旦修改 迭代器就失效了! 这是非常严重的错误);

因此 一定要进行if( mp.find( x) != mp.end()){ ...}的判断, 只有他是存在于容器中时 再访问他 (这样就不会插入新元素了); (非常重要!)

例题: LINK: https://editor.csdn.net/md/?not_checkout=1&articleId=131933499;

初始化列表 不可以使用emplace_back

vector< vector<int> > A, 需求是往里面添加一个vector<int>{1,2,3}的对象;

使用A.emplace_back( 1, 2, 3)是错误的, 因为vector<int>并没有一个 形如vector( int, int, int)构造函数;
. vector< T>::emplace_back( a,b,c)的本质, 就是调用T(a,b,c)的构造函数;

使用A.emplace_back( {1,2,3})是错误的;
. 很容易认为这是正确的, 因为vector<int>( {1,2,3})是正确的; 只能说 这个构造函数 并不是正统的, 因为他接收的是初始化列表;
. 所以这很特别, 这种用法是不可以的;

正确的是: A.push_back( {1,2,3});

不要让宏作运算

#define M_( _a, _b) _a * _b * _b;

当你使用M_( x - 1, y - 1)时, 他是x - 1*y - 1*y - 1; 解决方法是 M_( _a, _b) (_a)*(_b)*(_b);

但你还会遇到问题, 比如M_( f(x), f(y)), 此时你的f(y)会执行2次, 你的本意是 让f(y)执行1次 只是他的返回值 执行2次, 因此 这也会出错;

因此, 宏定义 就让他做简单的文本替换的功能, 不要做运算;

全局容器变量要初始化

vector< int> A[10];

int main(){
	...
}

A[i] maybe not Empty!
You should operate A[i].clear();

%0模数为0

x % 0
Eroor: remainder by zero is undefined;

(*P)[M]二维指针的地址

constexpr int M = 10;
int x = 3;
T (*a)[ 10] = new T[ x][ 10];

a09 a19 a29
... ... ... 
a02 a12 a22
a01 a11 a21
a00 a10 a20

If you wanna locate at the element ai0, the pointer a + i * M is Wrong! cuz the type of a is T (*)[M], not T *;
. That is, the pointer a + i denotes the array ai0, ai1, ai2, ..., ai9, therefor a + i is the address of the element ai0;
. If you have another pointer b = &a00, then b + i * M corresponds to ai0;

1 < a < 3

if( 1 < a < 3){ ...}
這個代碼是錯誤的, 他會是: 1<a會變成一個0/1的布爾值b 然後b < 3;
正確代碼是if( 1<a && a<3){ ...}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值