字符串处理函数(四):strstr

时间:2022-01-24 22:17:38

字符串查找函数,下面是最笨的方法的一种实现,并没有采用一些高效的如KMP算法:

如果简单写写,大概很多人会按照下面这种写法来写:

 

的确,由于要保证不能对两个字符串修改,添加了const关键字,而且使用的临时变量p、s1、s2都是const char *类型,这个代码是正确的,但是有时候为了减少不必要的空间申请,需要把循环中的变量定义移出到循环外,再加上对代码精简的考虑,很可能形成下面的一段代码:

 

我们发现代码的确精简了一些:1)变量移到循环外 2)p,s1,s2三个变量放在一起定义 3)s1,s2值的变化放到for循环中,这种改动初衷是好的,但是存在的问题是:在定义const变量时,p,s1,s2所指向的字符串是不循序更改的,由于初始化是并没有对p,s1,s2进行赋值,因此这三个指针很可能指到一个未知区域,而在while循环中却又要将指针指向另外一块地方,这是不行的。因此上面的代码虽然能通过编译,但是运行会出现异常。

也就是说,在定义const变量的时候,最好对其进行初始化,如

const char* p=str1;

const char* s1=str1;

const char* s2=str2;

但是,同样,由于每次查找不成功是需要对s1,s2指针进行重置操作,因此按上面这样将p,s1,s2放在外面定义并初始化依然达不到预计效果:s1=p;s2=str2;的操作是非法的。

 

因此,最好的解决方案是定义循环的i,j,k变量,然后只需要在str1,str2上进行偏移操作就行了,既减少变量定义,又不需要处理复杂的const char*的问题,代码如下:

 

这里仍然有一处不足,在处理k=i++的时候本意是重置搜索位置:如果未成功,从下一个i开始,但是没有考虑到for循环的执行顺序:for结构是for(初始化语句;往下执行的条件;变化、递增的”步长“),循序是先进行初始化,判断初始化后是否满足条件,满足则执行for循环体,执行一次使用”步长“变化一次,并执行下一次循环,如此往复直至循环条件不满足。也就是说,k=i++到第二次才能执行,而这时i=0,所以k的取值情况是:0(未执行k=i++,只是定义时赋的值),0(执行k=i++,但是由于i=0,执行完后i才变成1,k值仍为0),1,2......

 

因此对上面代码稍作修改: