White_Bear_ @ 2024-11-29 10:54:05
大家都知道,在让某个变量加一时,使用 ++i
之类的语句,可以让该变量先加一,在进入后续的赋值操作。
于是,笔者在做某道 01-trie 练习题时,在 new_node
函数中采用了如下写法:
trie[++tot][0] = trie[tot][1] = 0;
该写法下,笔者的代码通过了所有的大样例,但成功地获得了 8pts 的好成绩。
并且,将洛谷给出的错误数据输入本地的 exe 文件,得出的答案是正确的。
于是,笔者经过了许多尝试,发现只要把这行代码修改为:
++tot, trie[tot][0] = trie[tot][1] = 0;
就可以获得 100pts 的好成绩。
问题在于,作者在洛谷提交时选择的是 c++14,关闭 02 优化,在本地编译时的编译选项也是 -std=c++14
。
作为 oi 萌新,笔者并不知道是什么问题导致了 100 -> 8,但肯定的是,如果笔者在 noip 考场上犯了同样的问题,那必然是要 afo 了。
所以蒟蒻非常希望有大佬能给出靠谱的解答,谢谢。
by djfuck @ 2024-11-29 10:56:10
可能是 ub?
by djfuck @ 2024-11-29 10:56:54
编译器可以先执行 trie[tot][1] = 0
也可以先执行 trie[++tot][0] = 0
(这里其实 tot
已经自增过了),不同编译器可能有不同的处理顺序。
by bcdmwSjy @ 2024-11-29 10:57:39
@WhiteBear
这是 ub,在不同坏境下表现可能不同,尽量不要写这种东西。
by Kev1nL1kesCod1ng @ 2024-11-29 10:59:38
大神 /bx /bx /bx
by qiminghaonan @ 2024-11-29 11:00:14
注:c++17之后,所有赋值都必须先算右边再算左边,但是还是尽可能不要这么写吧
by Kev1nL1kesCod1ng @ 2024-11-29 11:02:33
就是原理应该是先执行trie[tot][1] = 0
,然后这个返回 trie[tot][1]
然后再赋值给 trie[tot][0]
。
所以应该要写 trie[++tot][1]
但是这玩意很危险,还是别用了
by M_WC1S_M0 @ 2024-11-29 11:02:56
csp-s2024 320分的OI萌新
@Illus1onary_Real1ty 太强了
by Illus1onary_Real1ty @ 2024-11-29 11:06:01
谢谢大家的帮助,再也不敢这么写了(
by Kev1nL1kesCod1ng @ 2024-11-29 11:07:41
@Illus1onary_Real1ty
/bx /bx /bx