博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字符串函数的实现, memmove() 函数的实现和解析
阅读量:3949 次
发布时间:2019-05-24

本文共 3125 字,大约阅读时间需要 10 分钟。

  • strlen 函数的实现
int my_strlen(char* dst) {
assert(dst); char* ret = dst; int count = 0; while (*ret!='\0') {
++ret; ++count; } return count;}
  • strcat 函数的实现
har* my_strcat(char* dst, const char* src) {
assert(dst && src); char* ret = dst; // 因为后边 dst需要++,所以用ret保存原来的位置 while (*dst != '\0') {
//先找到 dst 上'\0' 的位置 ++dst; } while (*dst++ = *src++); //当 dst 到 '\0'了,再将 src 传给 dst return ret;}

和strcpy 不同的是 strcpy是拷贝,strcat是追加拷贝。

  • strcmp 函数的实现
int my_strcmp(const char* str1,const char* str2) {
assert(str1 && str2); unsigned char* s1 = (unsigned char*)str1; unsigned char* s2 = (unsigned char*)str2; while (*s1 && *s2) {
if (*s1 > *s2) {
return 1; } else if (*s1 < *s2) {
return -1; } else {
++s1; ++s2; } } if (*s1 == '\0'&&*s2 == '\0') {
return 0; } else if (*s1 == '\0') {
return -1; } else {
return 1; }}

strcmp 函数居然是根据字符串中字符的 ASCII 码大小来比较字符串大小的,我有一点不解,假如有两个字符串 str1 = “abbb” 和 str1 = “baaa”,用 strcmp 函数的话,结果是 str2 大于 str1,仅仅是因为 str2 的第一个字符 b 的 ASCII 码大于 str1 的 a。我的想法是应该比较总的 ASCII 码的大小。(仅仅是我自己的臆想,还是按照人家的来吧!)

  • strstr 函数的实现
    判断一个字符串是不是另一个字符串的子串,如果是,则该函数返回 str2 在 str1 中首次出现的地址,否则,返回NULL。
char* my_strstr(const char* src, const char* sub) {
assert(src && sub); const char* srci = src; const char* subi = sub; while (*srci != '\0') {
while (*srci == *subi && *subi != '\0') {
++srci; ++subi; } if (*subi == '\0') {
return src; } else {
subi = sub; ++src; srci = src; } }}
  • memcpy 函数的实现
void* my_memcpy(void* dst, const void* src, size_t num) {
assert(dst && src); char* str_dst = (char*)dst; char* str_src = (char*)src; for (size_t i = 0; i < num; ++i) {
str_dst[i] = str_src[i]; // 等价于 *(str_src + i) } return dst;}

memcpy函数和strcpy函数的一个区别在于,memcpy可以拷贝任意类型的数据,而strcpy函数只能拷贝字符串

  • memmove 函数的实现

    memmove 函数有两种实现的方法。

    在这里插入图片描述
    如图要将红色部分的数据拷贝到黑色部分,第一种情况是内存的前重叠,和不重叠,直接从 src 的前往 src 的后拷贝给 dst,不会影响结果。但是如果是内存的后重叠,如下图:
    在这里插入图片描述
    如果还是按照从前往后进行拷贝,把 src 的第一个数据拷给 dst 的第一个数据时,就已经改变了 src 后边的数据,因为 dst 第一个数据所在位置刚好重叠与 src 后边的数据,这样拷贝,已经改变了还没有拷贝给 dst 的数据,后边拷贝的数据并不是我们最初想要的。所以这种内存后重叠,我们就要从后往前进行拷贝,也就是说,先把 src 的最后一个数据拷贝给 dst 的最后一个数据,然后把 src 的倒数第二个数据拷贝给 dst 的倒数第二个数据,以此类推。这样做就不会改变还没有拷贝给 dst 的 src 数据。
    以下有两种拷贝方式,第一种是:给前重叠或者不重叠从前往后拷贝,给后重叠或者不重叠从后往前拷贝(从前往后或者从后往前拷贝都不会影响到内存不重叠的拷贝)。 第二种是:给内存前重叠或者不重叠的从前往后拷贝,给内存后重叠的从后往前拷贝。

    第一种

void* my_memmove(void* dst, const void* src, size_t num) {
assert(src && dst); char* str_dst = (char*)dst; char* str_src = (char*)src; if (str_dst < str_src) {
//前重叠或者不重叠,从前往后拷贝 for (size_t i = 0; i < num; ++i) {
str_dst[i] = str_src[i]; } } else {
//后重叠或者是不重叠,从后往前拷贝 for (int i = num-1 ; i >= 0; --i) {
str_dst[i] = str_src[i]; } } return dst; }
**第二种**
void* my_memmove(void* dst, const void* src, size_t num) {
assert(src && dst); char* str_dst = (char*)dst; char* str_src = (char*)src; if (str_src < str_dst && str_dst
= 0; --i) {
str_dst[i] = str_src[i]; } } else {
//前重叠或者不重叠,从前往后拷贝 for (size_t i = 0; i < num; ++i) {
str_dst[i] = str_src[i]; } } return dst;}

值得一提的是,字符串数组可以用这种方式初始化(char str[] = “abcdefg”),但是不可以用这种方式赋值,这里就可以用到字符串函数 strcpy memcpy memmove

转载地址:http://qqwzi.baihongyu.com/

你可能感兴趣的文章
算法相关——Java排序算法之归并排序(八)
查看>>
Android开发——BroadcastReceiver知识总结
查看>>
算法相关——KMP算法最通俗易懂的解释
查看>>
Android开发——监控造成UI卡顿的原因
查看>>
设计模式——设计模式三大分类以及六大原则
查看>>
Java技术——同步锁的各种知识总结
查看>>
Android开发——适配终结者AutoLayout
查看>>
Android开发——ListView局部刷新的实现
查看>>
Java技术——Java中的参数传值方式
查看>>
Android开发——本地验证码的简易实现
查看>>
Java技术——CopyOnWriteArrayList源码解析
查看>>
Java技术——ReentrantLock的Condition的作用以及使用
查看>>
数据结构——搜索树树、B-树、B+树
查看>>
Android开发——带你彻底理解 Window 和 WindowManager
查看>>
设计模式——责任链模式详解
查看>>
设计模式——适配器模式详解
查看>>
设计模式——装饰模式详解
查看>>
Android开发——关于RxJava的知识总结
查看>>
Android开发——View的生命周期总结
查看>>
Android开发——Protocol Buffer的使用(比XML、Json快很多)
查看>>