代码克隆的类别总结

来源:互联网 发布:java中复制文件夹 编辑:程序博客网 时间:2024/06/08 16:14

写在前面的话

这篇文章是翻译了 A Survey on Software Clone Detection Research这篇文章的第7小节,作者是:Chanchal Kumar Roy and James R. Cordy
在语言上我做了一些修改,让它比较符合我说话的习惯。


所有不懂的事情自己一点点弄明白。加油,doggy~

对于两个代码片段来说,基本来说有两种相似性。对于两个相似的代码段,要么是它们的程序文本相似(代码的某些片段相似)要么是它们的功能是相似的但是程序的文本没有任何相似的地方。

对于第一类代码克隆(code clone)来说主要的原因就是复制了某个代码片段然后把它粘贴到了其他你需要的地方。

对于代码克隆我们主要把它们分为文本相似功能相似


文本相似:

我们基于文本相似把代码可能分为了下面的三类:

【类型一】: 代码片段是完全相同的,除了空格,代码的布局格式或者是注释不同

【类型二】:代码的结构或者是代码的语法构成都是相同的,除了用户定义的变量,常量值,类型,布局或者是注释有不同

【类型三】:复制粘贴的代码片段被做了一些改动。除了在类型二上的变动之外,程序本身可能增加,删除修改了部分语句


功能相似性

【类型四】:如果两个代码片段的功能是相似的或者是完全相同的, 例如:他们有相同的前后条件,我们把这种叫做语义克隆


**
这些克隆的的类型从类型1到类型4他们的变化是逐级递增的,同样的他们的分析难度以及检测难度也是逐级递增的。类型1最低,类型4最难。检测类型4的代码克隆需要大量的程序构建背景知识和软件设计的背景知识。

下面我们给每个程序克隆举几个例子。

类型一

类型一其实就是复制的代码片段和原来的代码片段是一样的。但是他们在空格或者是在行,tabs这些地方有些许的不同,注释和布局的地方也有不同。类型一就是我们广泛知道的精确克隆。

考虑下面的代码段:

 if ( a >= b){       c = b + d; //coomment 1       d = d + 1; } else       c = d-a;  //comment 2

一个精确的代码复制能够如下所示:

if ( a>= b){    //comment    c=d+b;    d=d+1;}else //comment2    c=d-a

我们可以发现上面的这两段代码片段都是文本相似的是(甚至是在移出了空格和注释以后,行和行之间都是相似的)当然就算移出了空格和注释,在结构上是不同的,但是我们也认为这是类型一,如下面这段代码所示:

if(a>=b){   //comment 1    c=d+b;    d=d+1;}else //comemnt2c=d-a

但是现有的一行一行检测对比技术对于第一个代码段和第三个代码段可能就会失效。

类型二

类型二的克隆代码段和原始的代码段大部分是相同的,除了用户自定义的标识符(变量名,常量名,类名,方法名),布局和注释不同。 系统自定义的关键字(保留字)和句子的结构是完全和源代码一直的。

下面来看下面的代码片段:

if(a>=b){    c = d + b; //comment    d = d + 1;}else    c = d - a; //comment

类型二的代码克隆片段:

if (m>=n){ //comment1'    y = x + n;    x = x + 5; //comment3}else    y = x - m; //comment2

对于上面的两个代码片段我们可以看出来,在布局,变量名和赋值语句上都有很大的区别。但是它们在语法的结构上是相似的。


类型三

类型三在语句上做了更多的修改。比如说:增加,删除,修改。

考虑下面的代码片段:

if (a>=b){    c = d + b; //comment1    d = d + 1;}else    c = d - a; //comment2

如果我们在我们的这段代码中添加一个语句 e=1 之后我们可以得到

if (a>=b){    c = d + b; //comment1    e = 1; // This statement is added    d = d + 1;}else    c = d - a; //comment2

像这样插入一条新的语句就是我们说的类型三。

我们在看一个例子:
下面的这个代码片段不同的地方我们将在表格中展现出来。

这里写图片描述

两个代码段不同的地方
这里写图片描述

类型四

类型四指的是语义上相似的代码片段。对于这种类型的复制,克隆的代码片段并不需要复制原始的代码。两个代码甚至有完全不同的执行逻辑。

看下面的两个代码段。
他们都是实现阶乘,一个用了循环,一个用了递归,最后的执行结果是完全相同。

这里写图片描述

这里写图片描述



写在后面的话

如果我说不吻你不罢休,谁能逼我将就

我没有不快乐,只是还有一点淡淡的心痛,有时候明知道一段感情像无底洞,有始无终,还是愿意挂念还是不愿放手。

我今天很想你,很想很想,我也不知道是在想你还是想我为你规划的未来的所有美好

你必需非常努力才可以看起来毫不费力,狗狗加油~

                                        my dear Mr. lovable
0 0