有关不调用库函数的字符串操作!
char *strstr(char *str1,char *str2);在字符串str1中,寻找字串str2,若找到返回找到的位置,否则返回NULL。
#include <iostream>
char *strstr(char *str1,char *str2)
{
char *s1,*s2;
assert(( str1 != (char *)0 && (str2 != (char *)0));
/* 空字符串是任何字符串的子字符串 */
if('/0' == *str2)
{
return ((char *)str1);
}
while(*str1)
{
s1 = (char *)str1;
s2 = (char *)str2;
while((*s1 == *s2) && *s1 && *s2)
{
s1++;
s2++;
}
if('/0' == *s2)
{
return ((char *)str1);
}
str1++;
}
/* 查找不成功,返回NULL */
return((char *)0);
}
void *memcpy(void *pvTo, const void *pvFrom, size_t size)
{
assert((pvTo != NULL) && (pvFrom != NULL)); // 使用断言
byte *pbTo = (byte *) pvTo; // 防止改变pvTo的地址
byte *pbFrom = (byte *) pvFrom; // 防止改变pvFrom的地址
while(size -- > 0 )
*pbTo ++ = *pbFrom ++ ;
return pvTo;
}
第二种:转自变态之MEMCPY
void* mymemcpy( void* dest, const void* src, size_t count )
{
char* d = (char*)dest;
const char* s = (const char*)src;
int n = (count + 7) / 8; // count > 0 assumed 没有检查count为0的情况
switch( count & 7 )
{
case 0: do { *d++ = *s++;
case 7: *d++ = *s++;
case 6: *d++ = *s++;
case 5: *d++ = *s++;
case 4: *d++ = *s++;
case 3: *d++ = *s++;
case 2: *d++ = *s++;
case 1: *d++ = *s++;
} while (--n > 0);
}
return dest;
}
解释:
int n = (count + 7) / 8;计算要复制的轮数(每轮复制8位),剩下的余数位数也要复制进去。
count & 7控制要复制余数位数,while (--n > 0)控制轮数。
比如count = 9,则n = 2,count & 7 = 1,要复制2轮,程序跳到case1执行,复制一位之后,再循环一轮,复制8位.
为何这么实现:引用上面帖子后面的评论:
每8个字节拷贝省7个跳转(AMD处理器内部分支预测算法是“假定全都跳转”,因此这里也就是相当于省了7个时钟周期);把swith和do循环凑到一起,多少省几个字节的空间……
但使用32位或64位指令,可以得到更大的优化效果,代码还要精炼得多。
说实在话:除非内存小到极点、并且无法增加的系统,写出这样的程序纯属作孽……
后记:一般出题目让你实现memcpy,个人理解,其意图至少有以下几点:
1.写任何程序都能反映出你的代码风格.
2.考查你是否注意到,要拷贝的源,即const void* src,应该是用const的,避免有意或无意的修改.
3.指针的类型转化问题,原始参数应该是void *的,你具体操作的时候,应该是转化为某种具体的类型,此处用char比较适合.
4.注意要判断源src是否和dest重复,如果重复,直接返回或返回错误.
5.应该还有其他考虑,如果以后想到,再补充.
//字符串拷贝:
char *strcpy(char *strDest, const char *strSrc)
{
assert((strDest!=NULL) && (strSrc !=NULL)); // 使用断言
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘/0’ )
return NULL ;
return address ;
}
//strrpl库函数:
/* 把 s 中的字符串 s1 替换成 s2 */
char *strrpl(char *s, const char *s1, const char *s2)
{
char *ptr;
while (ptr = strstr(s, s1)) /* 如果在s中找到s1 */
{
memmove(ptr + strlen(s2) , ptr + strlen(s1), strlen(ptr) - strlen(s1) + 1);
memcpy(ptr, &s2[0], strlen(s2));
}
return s;
}
//内存拷贝:
#include <iostream>
using namespace std;
void* memcpy(void* dest,const void *src,size_t count)
{
char* pdest=static_cast<char*>(dest);
const char* psrc = static_cast<const char*>(src);
if(pdest>psrc && pdest<psrc+count)
{
for(size_t i=count-1; i!=-1;i--)
pdest[i]=psrc[i];
}
else
{
for(size_t i=0;i<count;i++)
pdest[i]=psrc[i];
}
return dest;
}
//查找字符在字符串中出现的次数:
int count1(char* str,char* s)
{
char* s1;
char* s2;
int count = 0;
while(*str!='/0')
{
s1 = str;
s2 = s;
while(*s2 == *s1&&(*s2!='/0')&&(*s1!='0'))
{
s2++;
s1++;
}
if(*s2 == '/0')
count++;
str++;
}
return count;
}