memcpy, strcpy, strlen, strcmp, itoa, atoi 的函数实现

时间:2023-01-13 16:12:53

不使用库函数,实现 memcpy, strcpy, strlen, strcmp, itoa, atoi.
本文地址 : http://blog.csdn.net/quzhongxin/article/details/48136245

1. memcpy

内存拷贝函数。
函数原型

void *memcpy(void*dest, const void *src, size_t n); // n 为字节数

注意问题:
1. 判断输入地址有效性
2. 将src,dst 指针强制转换成字符型指针,逐字节复制
3. 结束复制的依据是否已经复制了len个字节,而不是’\0’ 或 数据个数
4. 重叠问题,写入 dst 的数据会覆盖 src 未使用的数据时,需要从后往前复制

// 注意问题 1. 输入有效性 2. 重叠问题
void* MyMemcpy(void* dst, const void* src, size_t len) {
if (dst == NULL || src == NULL || len <= 0)
return NULL;
char* pDst = (char*) dst;
const char* pSrc = (const char*) src;
if (pDst > pSrc && (pDst-pSrc) < len) {
// 有重叠,从后向前复制
for (int i = len-1; i >= 0; i--)
pDst[i] = pSrc[i];
} else {
// 无重叠,从前向后复制
for (int i = 0; i < len; i++)
pDst[i] = pSrc[i];
}
return dst;
}

2. strcpy

字符串拷贝函数,将 src 的字符拷贝到 dst .
以 ‘\0’为结束标志。

char* MyStrcpy(char* dst, const char* src) {
if (dst == NULL || src == NULL)
return dst;
char* dst_origal = dst;
while (*dst++ = *src++);
return dst_origal;
}

3. strlen

统计一个字符串,从起始地址到’\0’的字符 的字符个数(不计’\0’)

size_t MyStrlen(const char* str) {
if (str == NULL)
return 0;
size_t size = 0;
while (*str++ != '\0')
size++;
return size;
};

4. strcmp

C/C++函数,比较两个字符串
设这两个字符串为str1,str2,

  • 若str1==str2,则返回零;
  • 若str1 > str2,则返回正数;
  • 若str1 < str2,则返回负数。
int MyStrcmp(const char* str1, const char* str2) {
int result = 0;
assert(str1 != NULL && str2 != NULL);
while (*str1 && *str2 && *str1 == *str2) {
str1++;
str2++;
}
return *str1 - *str2;
}

5. atoi

字符串转整型

  • 1 检查输入有效性
  • 2 过滤开始的空格
  • 3 处理正负号
  • 4 累加并检测溢出
// 需要注意 0. 无效输入 1. 空格 2. 正负号 3.溢出
int MyAtoi(const char* str) {
const int kIntMax = ~((unsigned int)0) >> 1;
const int kIntMin = -kIntMax - 1;
if (str == NULL || *str == '\0') {
cout << "Input Valid" << endl;
return 0;
}
long long result = 0; // 处理溢出
while (*str == ' ')
str++;
bool minus = (*str == '-') ? true : false;
if (*str == '-' || *str == '+')
str++;
while (*str >= '0' && *str <= '9') {
result = result*10 + (*str - '0');
if (!minus && result > kIntMax)
return kIntMax;
if (minus && -result < kIntMin)
return kIntMin;
str++;
}
return minus ? -result : result;
}

6. itoa

将整型数据转化为字符串

  1. 检查目标字符串是否为NULL
  2. 处理正负号
  3. 将整型数据的从低位到高位,以字符的形式写入到 temp 字符串
  4. 如果是负数,首位写入’-‘;将 temp 字符串逆序复制到目标字符串
  5. 添加结束字符 ‘\0’
// 先从低位开始将每一个字符写到temp串,再copy到目标字符串
// 需要注意 0. 目标串尾NULL 1. 对0的处理 2. 对负数的处理
char* MyItoa(int num, char* result) {
if (result == NULL) {
return NULL;
}
char* temp = new char[20];
bool minus = num < 0 ? true : false;
if (num < 0) {
num = -num;
}
int i = 0, j = 0;
// do while 能处理 num = 0
do {
temp[i++] = (num % 10) + '0';
num /= 10;
} while (num != 0);

if (minus) {
result[0] = '-';
j++;
}
while (--i >= 0) {
result[j++] = temp[i];
}
result[j] = '\0';
delete[]temp;
return result;
}