本人刚刚在做树链剖分“染色”一题的代码重构,上午打爆了是在调不出来,只能从头来过
染色
bb一句:对于数据结构这种题,一旦打完后一到两个小时之内静态,动态查错都没有调出来
就应该果断删掉重构代码,重新想过(更好的其实是休息一会再调才不会跳入固定思维里面)
重构完后,我发现自己一遍过样例!!
但是就发现了贼nm离谱的运行,人直接给我整傻掉
先看看错误代码把…
博主把该有的操作和答案操作都去掉了,让我们直接来欣赏这份代码大礼包
友情提示:该题目的操作是Q或者C只有一个字符哦
char opt[1]; int a, b, c;
for( int i = 1;i <= m;i ++ ) {
scanf( "%s %d %d", opt, &a, &b );
if( opt[0] == 'C' )
scanf( "%d", &c );
}
看着是不是完美无瑕的亚子?!!!
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
别急着往下翻,再想想
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
你觉得这份代码没问题吧?
.
.
.
.
.
.
.
.
.
.
.
.
.
.
真的没有问题吗?
.
.
.
.
.
.
.
.
.
.
.
.
.
有的吧?
.
.
.
.
.
.
.
.
.
.
.
.
.
.
你发现了吗?!!
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
你怀疑自己之前的想法了吗?你还坚信是对的吗?
.
.
.
.
.
.
.
.
.
.
.
.
.
尽管一瞬的怀疑,可你马上否定,仍觉得这份代码没错的,对吧?
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
你开始产生怀疑了?
.
.
.
.
.
.
.
.
.
.
.
.
越来越怀疑
.
.
.
.
.
.
.
.
.
.
.
.
你越发觉得代码有点问题了?
.
.
.
.
.
.
.
.
.
.
.
可究竟错哪儿了?
.
.
.
.
.
.
.
.
.
.
.
.
冥冥之中,直觉开始作祟,有问题,却说不上来在哪?
.
.
.
.
.
.
.
.
.
.
.
.
代码错误的原因究竟是?
.
.
.
.
.
.
.
.
.
.
.
.
.
想不到
.
.
.
.
.
.
.
.
.
.
.
.
开始猜测各种情况
.
.
.
.
.
.
.
.
.
.
.
慢慢的,发现了一个比较靠谱的猜测
.
.
.
.
.
.
.
.
.
.
.
.
.
越发相信自己的猜测
.
.
.
.
.
.
.
.
.
.
.
.
现在怎么看,这份代码都有错了
.
.
.
.
.
.
.
.
.
.
.
.
坚持你的想法吗?你的想法是不是问题所在?
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
盲点,你发现了华生!!!
但!!!!!!!!!
准确来说,这份代码错了又没错
上图甩!走你┏ (゜ω゜)=☞
且看傻逼博主一步一步搞蒙自己
.
.
.
没错运行程序表明,死循环了。
死循环了???
死循环了!!!
怎么可能?!!
我想:换种写法试试,爷还不信了?
又好了???
结果显而易见了,肯定是 f o r for for循环的 i i i出问题了,
但是爷仔细一看,没啥啊,这不正常进行的吗,每个操作都被读入了
按道理 i i i应该老老实实的 + + ++ ++,可为何迟迟不到 m m m
早已掌握了分布调试诀窍的我马上开始 p r i n t f printf printf分步康康
i i i为什么一直等于 1 1 1!!!!
情况一出现凭借多年踩雷从未避开过的经验,我立马感知到可能是 % s \%s %s字符串劈里啪啦一堆猫病,并竟平时没少在那一块因为输入的多个空格多个换行栽跟头
但是以为这点小知识还是有的爷简单分析一波, % s \%s %s输入字符串,遇到空格换行就停,不会读入空格换行,数组从 0 0 0下标开始,是前闭后开 [ 0 , 1 ) [0,1) [0,1),一个字符装进去刚刚好啊
这种玄学RE,还是应该请教一下身边的621同学,她刚开始看到我对她一步步演示也是一个吃惊,可后来马上夺过我的键盘,先看变量定义是否用了 i i i,再用 j j j来替换了一下 i i i,发现仍是这样
在一旁思考了小会儿,倏地进行了一个修改
char opt[15];
程序成功结束,果然是字符串这方面的问题,意料之中,但是 o p t opt opt数组的大小却让我意料之外
接着,我马上缩小数组范围,继续观察
原来 2 2 2都能接受,也就是说必须至少要开字符串长度大小 + 1 +1 +1
可这是为什么?为什么!
因为换行,空格这些都会对字符串造成一定影响,所以我先猜测可不可能是 % s \%s %s后面的那个空格对输入造成了影响,话不多说,立马实践
很不幸,实践表明,后面的空格并没有对它产生任何影响
那么就只剩下一种可能了
尽管不可思议
却仍然可能
真是让人难以置信
没错!就是,只能是,也必须是,输入一行后的换行对字符串造成了影响
可其实不然,这个表述有点歧义
因为字符串的确正确输入了,没有多的空格和换行
那换行怎么造成了影响?
因为!
换行符被变量 i i i“吸收”
!!
不可思议吧
可似乎只有这样才能解释,为什么 i i i迟迟不 + + ++ ++,而输入的操作能正确执行
实践再次证实了我的想法
换行符真的被 i i i读进去了
最后我得出我的想法,与君共享
.
.
.
.
.
.
.
因为 o p t opt opt只开到了 [ 1 ] [1] [1],所以相当于只申请了 0 0 0这个空间,用于储存输入操作字符 Q Q Q或者 C C C
也就意味着没有申请多余的空间给之前先读到的换行符
那么它就只能漂泊在外
但是这偌大的空间它不可能找不到位置放下自己
所以它随意乱跳看上了变量 i i i,私自占有了 i i i,将自己的值 0 0 0(ASCII码)赋给了 i i i
从而导致了 i i i的死循环
但是为什么偏偏是 i i i呢?系统独特设定?
我觉得不然,可能只是这份代码在这台电脑上的运行是赋值到 i i i
万一在其它地方,它又可以赋值到 a , b , c a,b,c a,b,c甚至是其他变量
此时就算换行符赋值了,后面的输入操作也会覆盖掉,并不对结果造成干扰
所以可能本地跑RE,交上去万一AC了呢
.
.
.
.
.
当然这些都是只是拙见,毕竟我还是个小蒟蒻
感觉一步一步过来就像完成了一个简略的科学探究应该有的步骤
发现问题
寻找问题源头
合理分析
提出猜想
实践证明
总结归纳
虽然目前我也不造这个想法对不对
计算机真的很神奇呢,里面有很多自己的小规则,这种看似玄学的背后竟然是
!
!
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
还是玄学
我要是有什么错误,欢迎指出,非常感谢能得到各位dalao的指导