1、memstr的实现
实现代码:
/**
* @brief 在字符串full_data中查找字符串substr第一次出现的位置
*
* @param full_data 源字符串首地址
* @param full_data_len 源字符串长度
* @param substr 匹配字符串首地址
*
* @returns
* 成功: 匹配字符串首地址
* 失败:NULL
*/
char* memstr(char* full_data, int full_data_len, char* substr) {
//异常处理
if (full_data == NULL || full_data_len <= 0 || substr == NULL) {
return NULL;
}
if (*substr == '\0'){
return NULL;
}
//匹配子串的长度
int sublen = strlen(substr);
int i;
char* cur = full_data;
int last_possible = full_data_len - sublen + 1; //减去匹配子串后的长度
for (i = 0; i < last_possible; i++) {
if (*cur == *substr) {
if (memcmp(cur, substr, sublen) == 0) {
//found
return cur;
}
}
cur++;
}
return NULL;
}
2、memcpy的实现
这里需要注意的就是内存覆盖,如图中1的情况。
实现代码:
/**
* @brief 从src内存地址拷贝n个字节到dst内存地址中
*
* @param dst 目标地址
* @param src 源地址
* @param n 字节长度
*
* @returns
* 成功: 目的地址dst
* 失败:NULL
*/
//单字节搬运版本:(
void* my_memcpy_byte(void *dst, const void *src, int n){
//异常情况
if (dst == NULL || src == NULL || n <= 0) return NULL;
char * p_dst = (char *)dst;
char * p_src = (char *)src;
//考虑内存覆盖的情况,就从后往前复制
if (p_dst > p_src && p_dst < p_src + n){
p_dst = p_dst + n - 1;
p_src = p_src + n - 1;
while (n--) *p_dst-- = *p_src--;
} else{
while (n--) *p_dst++ = *p_src++;
}
return dst;
}
//4字节搬运版本:),32位内存对齐情况下,性能比单字节版本高不少
void* my_memcpy_4byte(void* dst, const void* src, int n) {
//异常情况
if (dst == NULL || src == NULL || n <= 0) return NULL;
int* p_dst = (int*)dst;
int* p_src = (int*)src;
int len_4byte = n / 4;
int len_byte = n % 4;
char* tmp_src;
char* tmp_dst;
//考虑内存覆盖的情况,就从后往前复制
if (p_dst > p_src&& (char*)p_dst < (char*)p_src + n) {
tmp_dst = (char*)p_dst + n - 1;
tmp_src = (char*)p_src + n - 1;
while (len_byte--) *tmp_dst-- = *tmp_src--;
//因为int*和char*步长不同,所以在强转之前要移动到合适的地方,这里++移动一个字节
tmp_dst++;
tmp_src++;
p_dst = (int*)tmp_dst;
p_src = (int*)tmp_src;
//现在移动到了4个字节对齐的最后一个块的开头,这里--移动4个字节
p_dst--;
p_src--;
while (len_4byte--) *p_dst-- = *p_src--;
}
else {
while(len_4byte--) *p_dst++ = *p_src++;
tmp_dst = (char*)p_dst;
tmp_src = (char*)p_src;
while (len_byte--) *tmp_dst++ = *tmp_src++;
}
return dst;
}
3、strcpy的实现
/**
* @brief 将含有'\0'结束符的字符串从src复制到dst
*
* @param dst 目标地址
* @param src 源地址
*
*
* @returns
* 成功: 目标字符串地址ret
* 失败:NULL
*/
char* my_strcpy(char *dst, const char *src)
{
//异常情况
if (dst == NULL || src == NULL) return NULL;
char* ret = dst;
my_memcpy_byte(dst, src, strlen(src)+1);
return ret;
}