本文给出了一些字符串及内存操作的函数的实现:memcpy、memset、memmove、strcpy、strcmp、strlen、strstr、strcat,为了与标准区分,所有函数名前加了下划线。下面给出这些函数的实现。如果错误,还请读者指正。
//函数功能: 拷贝不重叠的内存块
//函数参数: dest指向目的,src指向源,size为拷贝的字节数
//返回值: 指向目的的指针
void * _memcpy(void *dest, const void *src, size_t count)
{
char *to = (char *)dest;
char *from = (char *)src;
assert(dest != NULL && src != NULL); //是否为空
assert(to >= from + count || from >= to + count); //判断是否重叠
while(count-- > 0)
*to++ = *from++;
return dest;
}
//函数功能: 把buffer所指内存区域的前count个字节设置成字符c
//函数参数: buffer指向内存块,c为填充值,count为填充字节数
//返回值: 指向内存块的指针
void * _memset(void* buffer, int c, size_t count)
{
char *to = (char *)buffer;
assert(buffer != NULL);
while(count-- > 0)
*to++ = (char)c;
return buffer;
}
//函数功能: 由src所指内存区域复制count个字节到dest所指内存区域
//函数参数: dest指向目的,src指向源,count为拷贝的字节数
//返回值: 指向内存块的指针
void * _memmove(void* dest, const void* src, size_t count)
{
char *to = (char *)dest;
char *from = (char *)src;
assert(dest != NULL && src != NULL);
if(to >= from && to < from + count) //目的内存区域的头部与源重叠,逆向复制
{
to = to + count - 1;
from = from + count - 1;
while(count-- > 0)
*to-- = *from--;
}
else
{
while(count-- > 0)
*to++ = *from++;
}
return dest;
}
//函数功能: 字符串拷贝
//函数参数: dest指向目的,src指向源
//返回值: 指向目的串的指针
char * _strcpy(char *dest, const char *src)
{
char *save = dest; //保存返回值
assert(dest != NULL && src != NULL);
while((*dest++ = *src++) != '\0');
return save;
}
//函数功能: 字符串拼接,将src拼接到dest
//函数参数: dest指向目的,src指向源
//返回值: 指向目的串的指针
char * _strcat(char *dest, const char *src)
{
char *save = dest;
assert(dest != NULL && src != NULL);
for(; *dest; dest++);
while((*dest++ = *src++) != '\0');
return save;
}
//函数功能: 字符串长度
//函数参数: str指向求长度的字符串
//返回值: 长度
size_t _strlen(const char *str)
{
size_t len = 0;
assert(str != NULL);
while(*str++ != '\0')
len++;
return len;
}
//函数功能: 字符串比较
//函数参数: s1指向字符串1,s2指向字符串2
//返回值: 0为相等,负数为小于,正数为大于
int _strcmp(const char *s1, const char *s2)
{
assert(s1 != NULL && s2 != NULL);
while(*s1 == *s2++)
{
if(*s1++ == '\0')
return 0;
}
return *(unsigned char *)s1 - *(unsigned char *)--s2;
}
//函数功能: 字符串是否含某子串
//函数参数: str指向字符串,substr指向某子串
//返回值: 子串在字符串中出现的开始位置
char * _strstr(char * str, char *substr)
{
int len1 = _strlen(str);
int len2 = _strlen(substr);
int i, j, k;
for(i = 0; i < len1; i++)
{
k = i;
for(j = 0; j < len2 && k < len1; j++, k++)
{
if(str[k] != substr[j])
break;
}
if(j == len2)
return str + i;
}
return NULL;
}
//函数功能: 字符串比较,只比较n个字符
//函数参数: s1指向字符串1,s2指向字符串2,n为比较的字符数
//返回值: 0为相等,负数为小于,正数为大于
int strncmp(const char *s1, const char *s2, int n)
{
assert(s1 != NULL && s2 != NULL && n > 0);
while(n-- > 1 && *s1 == *s2)
{
if(*s1 == '\0')
return 0;
s1++;
s2++;
}
return *(unsigned char*)s1 - *(unsigned char *)s2;
}