您的位置:首页 > 其它

07库函数编写

2015-06-11 08:24 295 查看
1:字符串查找
给定一个字符串A,要求在A中查找一个子串B。如A="ABCDF",要你在A中查找子串B=“CD”。

初步代码如下:
int strstr(char *string, char *substring)

{
if (string == NULL|| substring == NULL)

return -1;


int lenstr = strlen(string);

int lensub= strlen(substring);


if (lenstr < lensub)

return -1;


int len = lenstr - lensub;

for (int i = 0; i <= len; i++) //复杂度为O(m*n)

{
for (int j = 0; j < lensub; j++)
{
if (string[i+j] !=substring[j])

break;

}
if (j == lensub)

return i + 1;

}
return -1;
}

针对这个strstr的函数,我觉得有点小问题。我查了一下C标准库的源码,它给的声明是这样的,两个参数都有const:
char *strstr(const char *haystack_start, const char *needle_start)
而且标准库中没有调用strlen函数,因为假如你是标准库的设计者,strlen()函数还没设计出来,你怎么去计算两个字符串的长度?是不是只能通过指针移动来实现,我觉得这些都是微软要考察的地方。
此外:还有int lenstr=strlen(string);这是不安全的?strlen函数的返回类型是size_t型,也就是无符号整型,假如我的数组长度很长(假如是用堆分配的,可以很大很大),长过2的31次方减1的话,会发生一处,你这lenstr就会变成负值了,所以用size_t类型最保险。

2:字符查找
在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。代码如下:
char FirstNotRepeatChar(char * pString)

{
if(!pString) return '\0';


const int tableSize = 256;

int hashTable[tableSize] = {0};
//存入数组,并初始化为0

char * pHashKey = pString;

while(*(pHashKey) != '/0')

hashTable[*(pHashKey++)]++;


while(*pString != '/0')

{
if(hashTable[*pString] == 1)

return *pString;


pString++;
}
return '\0'; //没有找到满足条件的字符,退出

}

3:[b]字符串拷贝

[/b] 题目描述:要求实现库函数strcpy,

原型声明:extern char*strcpy(char *dest,char *src);

功能:把src所指由NULL结束的字符串复制到dest所指的数组中。  

说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

分析:如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:

//2分
void strcpy( char *strDest, char *strSrc)

{
while( (*strDest++ = * strSrc++) !='/0' );

}

//4分
void strcpy( char *strDest,
const char *strSrc )
{
//将源字符串加const,表明其为输入参数,加2分

while( (*strDest++ = * strSrc++) !='/0' );

}

//7分
void strcpy(char *strDest,
const char *strSrc)
{
//对源地址和目的地址加非0断言,加3分

assert((strDest != NULL) && (strSrc != NULL) );

while( (*strDest++ = * strSrc++) !='/0' );

}

//10分
//为了实现链式操作,将目的地址返回,加3分!

char * strcpy( char *strDest,
const char *strSrc )
{
assert((strDest != NULL) && (strSrc != NULL) );

char *address =strDest;

while( (*strDest++ = * strSrc++) !='/0' );

return address;

}

4:部分库函数的实现
char *strncpy(char *strDes,
const char *strSrc, unsigned int count)
{
assert(strDes !=NULL && strSrc != NULL);

char *address = strDes;

while (count--&& *strSrc != '\0')

*strDes++ = *strSrc++;

*strDes = '\0';

return address;

}


//查找字符串s中首次出现字符c的位置

char *strchr(const char *str, int c)

{
assert(str !=NULL);

for (; *str != (char)c; ++ str)

if (*str == '\0')
return NULL;
return str;
}


int strcmp(const char *s, const char *t)

{
assert(s != NULL&& t != NULL);

while (*s&& *t && *s == *t)
{
++ s;
++ t;
}
return (*s -*t);

}
int strncmp(const
char *s, constchar *t, unsigned int count)

{
assert((s != NULL) && (t !=NULL));

while (*s && *t && *s == *t&& count --)

{
++ s;
++ t;
}
return (*s - *t);
}



char *strcat(char *strDes,
const char *strSrc)
{
assert((strDes != NULL) && (strSrc!= NULL));

char *address = strDes;

while (*strDes !='/0')

++ strDes;
while ((*strDes ++= *strSrc ++) != '/0')

NULL;
return address;

}
char *strncat(char *strDes,
const char *strSrc,unsigned int count)
{
assert((strDes != NULL) && (strSrc!= NULL));

char *address = strDes;

while (*strDes !='/0')

++ strDes;

while (count --&& *strSrc != '/0' )

*strDes ++ =*strSrc ++;

*strDes = '/0';

return address;
}



int strlen(const
char *str)
{
assert(str !=NULL);

int len = 0;
while (*str ++ != ‘\0’)

++ len;
return len;
}

//将字符串拷贝到新的位置
char *strdup_(char *strSrc)

{
if(strSrc!=NULL)
{
char *start=strSrc;

int len=0;
while(*strSrc++!='/0')

len++;

char *address=(char*)malloc(len+1);

assert(address!= NULL);


while((*address++=*start++)!='/0');
return address-(len+1);

}
return NULL;
}


char *strstr(const char *strSrc, const char *str)
{
assert(strSrc !=NULL && str != NULL);

const char *s = strSrc;

const char *t = str;
for (; *strSrc != '\0';++ strSrc)

{
for (s = strSrc,t = str; *t != '\0' && *s ==*t; ++s, ++t)

NULL;
if (*t == '\0')
return (char *) strSrc;

}
return NULL;
}

/* 功能:依次检验字符串s1中的字符,当被检验字符在字符串s2中也包含时,则停止检验,并返回该字符位置,空字符NULL不包括在内。*/
char *strpbrk(const
char *strSrc, const char*str)
{
assert((strSrc !=NULL) && (str != NULL));

const char *s;
while (*strSrc != '\0')

{
s = str;
while (*s != '\0')

{
if (*strSrc == *s)

return (char *) strSrc;

++ s;
}
++ strSrc;
}
return NULL;
}

void *memcpy(void *dest, const void *src, unsigned int count)

{
assert((dest !=NULL) && (src != NULL));

void *address = dest;
while (count --)
{
*(char *) dest= *(char *) src;

dest = (char *)dest + 1;

src = (char *)src + 1;

}
return address;
}

5:总结

1:判断指针参数是否为NULL
2:如果参数只读不写,则需要添加const
3:函数中尽量不要调用其他库函数
4:申请内存后,需要判断是否申请成功
5:如果是内存函数,则注意指针类型
http://blog.csdn.net/v_JULY_v/article/details/6417600
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: