天人合一之毕设——实践阶段2——代码局部插桩

这就开始实现前面说的局部对if-else分支、循环块的局部插桩了

其实思想很简单,只不过大家书写代码的方式千差万别,所以要考虑的情况还是蛮多的

一、if-else分支(桩=输出当前行

1. if/else/else if(...)   ...

2. if/else/else if(...)  {...}

1、2插桩需变成:if/else/else if(...)  { 桩  ...}

3.if/else/else if(...){

    ....    (在此处插桩即可)

}

4.if/else/else if(...)

{

    ...     (在此处插桩即可)

}

5.if/else/else if(...)

      ...

6.if/else/else if(...)

   {....}

5、6插桩需变成:

    if/else/else if(...)

       {  桩  ....}

插桩总共需要考虑这6种情形,但是代码中有一些可以合并的

、循环结构

1.for/while结构

(1)for/while(...)   ...

(2)for/while(...)  {...}

(1)/(2)插桩变成:

int cnt;

for/while(...)  {cnt++;  ... }

printf("%d\n",cnt);   (相当于要插三句桩,比if-else复杂一些)

(3)-(6)和上面相似,不一一列出来

2.do while结构

(1) do{

    ...

   }while(...);

(2) do

{

...

}while(...);

(3)do

{...

}

while();

这种情况注意下:不是在遇到}后插输出语句,而是在while语句后

do-while结构好的一点就是应该不会出现那种单行的无{}语句,遇到do之后只需要在后面找有while()的一行就可

三、多重循环

一开始我只考虑了前两块情况,没有注意到可能出现多重循环的可能,譬如:

int cnt1 = 0;

for(int i=0; i<n; i++){

    cnt1++;

    int cnt2 = 0;

    while(a){

       cnt2++;

    }

    output1(cnt2);

}

    output2(cnt1);

  这种情况要插入两个输出语句的桩,但是在检验循环语句的时候,先查到for循环,则output2会先被赋值为output,然后output1会覆盖output2的值成为output,所以应该输出output2的地方就输出不了,插桩失败。

  后来我的解决方式是在repeat_flag的基础上又设置了一个double_repeat_flag

  当double_repeat_flag为true时,重新设置一个output2,此时不会被覆盖,能正确输出

  不足是只能解决双重循环的问题。其实实现三重循环思路应该也差不多,但是有点麻烦,我不太愿意写了..先这样吧

补充:在实现后续操作过程中,发现双重循环的这种插桩方式对cnt2的总次数很难以利用和统计,故需要对以上操作进行更改

int cnt1 = 0;

int sum = 0;

for(int i=0; i<n; i++){

    cnt1++;

    int cnt2 = 0;

    while(a){

       sum+=1;

    }

}

     output1(sum); //放在外面比较好,不然会输出多次,这个暂时还没实现

    output2(cnt1);

   

  一想到在过一遍代码时还要考虑这么多复杂的情况就头大,事在人为,加油吧!











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值