一个关于语法的小问题

学术版

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


|