我是靠谱客的博主 单薄大雁,最近开发中收集的这篇文章主要介绍strcpy memcpy strcmp strlen strcat strstr strchr实现及辨析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.strcpy实现

以下是C标准库写法,其最大隐患是有可能 dst 的长度小于 strlen(src) + 1 造成越界访问,或是类似 strcpy(ptr + 1, ptr) 发生重叠造成无限循环。

#include <assert.h>
char* strcpy(char* dst, const char* src)
{
assert(dst);
assert(src);
char* ret = dst;
while ((*dst++ = *src++) != '');
return ret;
}

以下为改进后的版本,不会因为 dst 处于区间 (src, src + len) 而导致错误

#include <assert.h>
char* strcpy_s(char* dst, const char* src) {
assert(dst);
assert(src);
char* ret = dst;
int size = strlen(src) + 1;
if (dst == src) {
return ret;
}
/* 以下表示 dst 处于区间 (src, src + size) 而发生重叠,此时需要从后面开始拷贝 */
if (dst > src && dst < src + size) {
dst = dst + size - 1;
src = src + size - 1;
while (size--) {
*dst-- = *src--;
}
}
else {
//这里表示正常拷贝
while (size--) {
*dst++ = *src++;
}
}
return ret;
}

2.memcpy实现

#include <assert.h>
void* memcpy(void* dst, const void* src, size_t size) {
assert(dst);
assert(src);
void* ret = dst;
char* pdst = (char*)dst;
char* psrc = (char*)src;
if (pdst == psrc) {
return ret;
}
/* 如果 pdst 处于区间 (psrc, psrc + size) 则发生重叠 */
if (pdst > psrc && pdst < psrc + size) {
pdst = pdst + size - 1;
psrc = psrc + size - 1;
while (size--) {
*pdst-- = *psrc--;
}
}
else {	//无重叠
while (size--) {
*pdst++ = *psrc++;
}
}
return ret;
}

 3.strcpy与memcpy的区别

1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。

2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符""才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。

3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。

 4.strcmp实现

函数原型:extern int strcmp(const char* s1, const char* s2);

  • 当s1 < s2时,返回值 < 0
  • 当s1 = s2时,返回值 = 0
  • 当s1 > s2时,返回值 > 0

 注意:该函数是按字典序逐个字符进行比较,直到遇上不相同的字符或是''为止,和字符串长度没有关系。

#include <assert.h>
int strcmp(const char *str1, const char *str2)
{
assert(str1);
assert(str2);
int ret = 0;
while (!(ret = *str1 - *str2) && *str1) {
++str1;
++str2;
}
if (ret < 0) {
ret = -1;
}
else if (ret > 0) {
ret = 1;
}
return ret;
}

5.strlen实现

#include <assert.h>
size_t strlen(const char* str)
{
assert(str);
unsigned int len = 0;
while(*str++ != '')
++len;
return len;
}

 注意:strlen的结果不包含末尾的结束符'',而sizeof的结果包含'',并且sizeof作用于数组时是返回数组的大小。

6.strcat实现

 注意没有处理出现重叠的情况,如果两个指针相同会造成无限循环

char* strcat(char* str1, const char* str2) {
assert(str1);
assert(str2);
char* p = str1;
while (*p)
++p;
while (*p++ = *str2++);
return str1;
}

7.strstr 实现

函数原型:extern char *strstr(char *str1, const char *str2);

str1: 被查找的对象

str2: 要查找的目标

返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL

char *strstr(const char *str1, const char *str2) {
char *cp = (char*)str1;
char *s1, *s2;
if (!*str2)
return((char *)str1);
while (*cp) {
s1 = cp;
s2 = (char *)str2;
while (*s1 && *s2 && !(*s1 - *s2))
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
}

 8.strchr实现

函数功能:返回首次出现ch的位置的指针,返回的地址是被查找字符串指针开始的第一个与ch相同字符的指针,如果s中不存在ch则返回NULL 

char* strchr(const char *s, char ch)
{
assert(s);
while(*s != '' && *s != ch)
++s;
return *s ? s : NULL;
}

 

最后

以上就是单薄大雁为你收集整理的strcpy memcpy strcmp strlen strcat strstr strchr实现及辨析的全部内容,希望文章能够帮你解决strcpy memcpy strcmp strlen strcat strstr strchr实现及辨析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(32)

评论列表共有 0 条评论

立即
投稿
返回
顶部