字符串处理函数和内存处理函数的模拟实现

简介: 上述就是几个常见的字符串处理函数,我们来模拟实现的目的就是为了以后不能使用这种函数的时候能自己写,主要是学习方法。

一,字符串处理函数


425b0f475000442bbceb3c364b4dc998.png


上述就是几个常见的字符串处理函数,我们来模拟实现的目的就是为了以后不能使用这种函数的时候能自己写,主要是学习方法。


一,strlen的三种形式


1.计数器


#define _CRT_SECURE_NO_WARNINGS 1
//计数器
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
  int count = 0;
  assert(dest);
  while (*dest++) {
    count++;
  }
  return count;
}
int main() {
  char arr[] = "hello";
  printf("%d",my_strlen(arr));
  return 0;
}


2.递归


#define _CRT_SECURE_NO_WARNINGS 1
//递归
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
  assert(dest);
  if (!* dest)
    return 0;
  return 1 + my_strlen( dest + 1);
}
int main() {
  char arr[] = "hello";
  printf("%d", my_strlen(arr));
  return 0;
}


3.指针-指针


#define _CRT_SECURE_NO_WARNINGS 1
//指针-指针
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
  assert(dest);
  const char* p = dest;
  while (*p) {
    p++;
  }
  return p - dest;
}
int main() {
  char arr[] = "hello";
  printf("%d", my_strlen(arr));
  return 0;
}


二,strcmp模拟实现


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* arr1, const char* arr2) {
  assert(arr1 && arr2);
  while (*arr1 == *arr2 ) {
    arr1++;
    arr2++;
    if(*arr2=='\0')
    return 0;
  }
  return *arr1 - *arr2;
}
int main() {
  char arr1[20] = "hello ";
  char arr2[] = "world";
  int ret=my_strcmp(arr1, arr2);
  if (ret == 0) {
    printf("arr1=arr2");
  }
  if (ret < 0) {
    printf("arr1<arr2");
  }
  if (ret > 0) {
    printf("arr1>arr2");
  }
  return 0;
}


三,strcat模拟实现


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* res) {
  assert(dest && res);
  char* p = dest;
  while (*dest) {
    dest++;
  }
  while (*dest++=*res++) {
    ;
  }
  return p;
}
int main() {
  char arr1[20] = "hello ";
  char arr2[] = "world ";
  printf("%s\n", my_strcat(arr1, arr2));
  return 0;
}


四,strcpy模拟实现


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest,char * src) {
  assert(dest && src);
  char* p = dest;
  while (*dest++ = *src++);
  return p;
}
int main() {
  char arr1[20] = "hello ";
  char arr2[] = "world";
  printf("%s\n",my_strcpy(arr1, arr2) );
  return 0;
}


五,strstr模拟实现


#define _CRT_SECURE_NO_WARNINGS 1
//模拟实现strstr函数
//在arr1中找是否包含arr2数组
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2) {
  assert(str1 && str2);
  const char* s1 = NULL;
  const char* s2 = NULL;
  //如果*str2=0;则需要返回str1的地址,所以str1的地址不能变
  char* cp = str1;
  if (*str2 == '\0') {
    //由于我定义的是const类型的,所以返回时需要强制转换为char*类型
    return (char*)str1;
  }
  while (*cp) {
    s1 = cp;
    s2 = str2;
    while (*s1 && *s2 && (*s1 == *s2)) {
      s1++;
      s2++;
    }
    //这里必定是由上面的while中跳出来的,因为上面已经筛选过了,当*s2结束,返回当前cp的地址
    if (*s2 == '\0')
      return (char*)cp;
    cp++;
  }
  //要么是找不到,*s2为0,程序直接结束,要么也是找不到,直到*cp为0,返回空指针,要么因为*s1为0,返回空指针
  return NULL;
}
int main() {
  char arr1[] = "abdjkhgio";
  char arr2[] = "jk";
  char* ret = my_strstr(arr1, arr2);
  if (ret == NULL) {
    printf("No found!");
  }
  else {
    printf("%s", ret);
  }
  return 0;
}


六,strtok实现


#define _CRT_SECURE_NO_WARNINGS 1
//strtok函数实现
#include<stdio.h>
#include<string.h>
int main() {
  char arr[] = "abc@woaini.dd";
  char* p = "@.";
  char tmp[20] = {0};
  strcpy(tmp, arr);
  char* ret = NULL;
    //strtok的返回值是遇到标志的地址,所以之后都是从null开始,函数将标志改为了\0
  for (ret = strtok(tmp, p); ret; ret = strtok(NULL, p)) {
    printf("%s\n", ret);
  }
  return 0;
}


二,内存处理函数


一,模拟实现memcpy


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
//num指的是字节长度
void* my_memcpy(void* dest, const void* src, size_t num) {
  void* ret = dest;
  assert(dest && src);
  //这个函数是一个字节一个字节的传,为了能让多种数据都能使用该函数,强制转换为char*类型
  while (num--) {
    *(char*)dest = *(char*)src;
    dest = (char*)dest + 1;
    src = (char*)src + 1;
    //*(char*)dest++=*(char*)src++;
    //这种方法是错的 ,解引用强制转换了之后,在进行++操作时,强制转换的作用已经不存在了
  }
  return ret;
}
int main() {
  int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
  int arr2[10] = { 0 };
  //arr2要够长,不然容易栈溢出。
  my_memcpy(arr2, arr1, 20);
  for(int i=0;i<5;i++)
  printf("%d\n", *(arr2+i));
  return 0;
}


二,模拟实现memmove


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num) {
  void* ret = dest;
  assert(dest && src);
  if (dest < src) {
    while (num--) {
      *(char*)dest = *(char*)src;
      dest = (char*)dest + 1;
      src = (char*)src + 1;
    }
  }
  else {
    while (num--) {
      *((char*)dest + num) = *((char*)src + num);
    }
  }
  return ret;
}
int main() {
  int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
  my_memmove(arr1 + 2, arr1, 20);
  return 0;
}


注意事项:


831ec0cac42549a882cdd5cc220db635.jpg


memcpy函数应该拷贝不重叠的内存


memmove函数可以处理内存重叠的情况。


memcpy按C语言的要求只能实现拷贝不重叠的内存,但是VS中可以实现拷贝重叠的内存。

目录
相关文章
|
3月前
|
C语言
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
46 0
|
23天前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
|
23天前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
|
28天前
【C初阶】内存函数:memcpy+memmove+memset+memcmp
【C初阶】内存函数:memcpy+memmove+memset+memcmp
|
2月前
|
存储 缓存 C语言
【C语言】字符函数,字符串函数,内存函数
C语言中的字符串函数和内存函数
31 0
【C语言】字符函数,字符串函数,内存函数
|
3月前
|
C语言
【C语言】:4大内存函数
【C语言】:4大内存函数
21 2
|
3月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
35 0
|
3月前
|
程序员 C语言
C语言内存管理:malloc、calloc、realloc与free函数详解
C语言内存管理:malloc、calloc、realloc与free函数详解
|
3月前
|
C语言
C语言内存函数
C语言内存函数
24 0
|
3月前
|
C语言 C++
C语言----C语言内存函数
C语言----C语言内存函数

热门文章

最新文章