教你如何篡改C++STL库,坑机房队友的时代到了

背景:

最近我们机房喜欢猜球——NBA某两队最终分差 ≥ 还是 ≤ 10。对于每一场的猜输者,累加他的出现次数,再用一个随机序列代码,排出一个序列。序列上的人从前往后打水去。

代码如下:
#include//此代码来自zzy
#include
#include
using namespace std;
int a[7]={0,1,2,3,3,4,5};//数字是人名的代号
int main()
{
	srand(time(0));
	for(int i=1;i<=30000;i++)
		random_shuffle(a+1,a+1+6);
	for(int i=1;i<=6;i++) printf("%d ",a[i]);
	return 0;
}

然而,机房zzy不满足,打水太累了,于是他将代码改了改 (他自己是3):

#include
#include
#include
using namespace std;
int a[7]={0,1,2,3,3,4,5};
int main()
{
	srand(time(0));
	while(a[5]!=3 || a[6]!=3)
		random_shuffle(a+1,a+1+6);
	for(int i=1;i<=6;i++) printf("%d ",a[i]);
	return 0;
}

zzy还道:“你们看看这份代码有什么问题?” 但是很快就被机智聪明的我们发现了。但我想,我们是否可以更改STL库,神不知鬼不觉地坑队友。

正文

一、如何进入STL库:
  1. 按住Ctrl+鼠标左击 要更改的函数词(例如random_shuffle)
    会进入如下页面
    教你如何篡改C++STL库,坑机房队友的时代到了_第1张图片
  2. 在计算机中查找stl_algo.h
    当然我可以直接告诉你它在 C:\Program Files\Dev-Cpp\MinGW32\lib\gcc\mingw32\4.8.1\include\c++\bits

我们知道上面的__first , __last 就是我们传上去的函数头尾的地址。
那么我们把STL上的代码拷下来,并按照格式先打一份目标代码:

#include
#include
#include
using namespace std;
int a[7]={0,1,2,3,3,4,5},tt=0;
void rs(int first,int last)
{
	if(first==last) return;
	int y;
	if(tt==0) { tt++; std::swap(a[first+1],a[last-1]); }
	for(int i=first+1;i!=last-1;++i)
	{
		y=first+rand()%(i-first+1);
		/*显然i最大为last-2 而rand()%(last-2-first+1)=
		rand()%(last-first-1)
		0 <= rand()%(last-first-1) <= last-first-2
		也就是说随机数永远都不会改变a[last-1]的值  */
	   	std::swap(a[i],a[y]);
	}
}
int main()
{
	srand(time(0));
	for(int i=1;i<=30000;i++)
	//	random_shuffle(a+1,a+1+6);
	rs(1,1+6);	
	for(int i=1;i<=6;i++) printf("%d ",a[i]);
	return 0;
}

//因为怕有读者看不懂,在这里解释一下代码:
//swap是交换两个值的函数,rand()是返回一个随机的数

我是2,这样可以保证每一次2都在最后,但这样做过于明显,所以可以自主地加一些优化:比如说奇数次运行代码我在最后,偶数次在倒数第2。这些就留给机智聪明的读者们想了。

二、修改STL库:

在这里,我必须要说一个坑点,STL有两个地方要改:
教你如何篡改C++STL库,坑机房队友的时代到了_第2张图片
好,说正事:
教你如何篡改C++STL库,坑机房队友的时代到了_第3张图片
眼尖的本作者看到了Random,但是我不需要随机,所以我们大胆改造,全变成int
教你如何篡改C++STL库,坑机房队友的时代到了_第4张图片
(由于不知名原因不改Random会报错,所以只好更改了……) :

但改成 int 后悲剧了,按下F11后:
教你如何篡改C++STL库,坑机房队友的时代到了_第5张图片
但我眼尖地发现除掉Random之后很大一部分是Iterator,所以我么大胆猜测,将所
有_RandomAccessIterator改成_Iterator,上代码:

	int __tt=0;
    template<typename _Iterator>
    void
    random_shuffle(_Iterator __first,_Iterator __last)
    {
      // concept requirements
      if (__first == __last)
	  return;
	 	if(__tt==0) { __tt++; std::iter_swap(__first+1,__last-1); }
		for(_Iterator __i=__first+1;__i!=__last-1;++__i)
		   	std::iter_swap(__i,__first+rand()%(__i-__first+1));
    }

最后,我们的面板为:除了上述代码外,其他有关的都屏蔽掉:

记得改完一定要按F11,不会报错,下面会显示红色的return 1 是正常的。

教你如何篡改C++STL库,坑机房队友的时代到了_第6张图片
最后,我们再打回原代码,继续向机房队友炫耀“你们看看这份代码有什么问题?”
然后,挖出大坑等着队友来跳:

#include
#include
#include
using namespace std;
int a[7]={0,1,2,3,3,4,5};//数字是人名的代号
int main()
{
	srand(time(0));
	for(int i=1;i<=30000;i++)
		random_shuffle(a+1,a+1+6);
	for(int i=1;i<=6;i++) printf("%d ",a[i]);
	return 0;
}

同志们,篡改C++STL库,坑机房队友的时代到了,让我们起航吧。

后记:

1.笔者自己并不知道STL内的格式,深表惭愧,但代码还是可以用的,以后若是有机会(有能力),再介绍一下STL的书写格式。

2.篡改STL需小心,不然以后调代码时可能会莫名出错,建议另找一台机试试,或打屏蔽保护原代码,如果已经出现了问题,可以到另一台机拷它的STL库来替换。

3.笔者自己曾手贱自建了一个stl_algo.h的C++文件,还运行了,以致Ctrl+左击回不去原STL,像这种情况,直接回 C:\Program Files\Dev-Cpp\MinGW32\lib\gcc\mingw32\4.8.1\include\c++\bits
将原stl_algo.h运行一遍就好了。

你可能感兴趣的:(杂项)