【C字符串函数】字符串函数和内存操作函数模拟实现(进阶版)(一)

简介: 【C字符串函数】字符串函数和内存操作函数模拟实现(进阶版)

0.说在前面的话:

  • 字符串函数的基本使用要包含头文件:#include<string.h>
  • 字符串以’\0’作为结束标志,
  • 字符串函数出现的size_t就是unsigned int无符号整型
  • 下面出现的assert是断言,要包含头文件**#include<assert.h>**
  • 下面的介绍我将从🚗重要知识🚗函数原型🚗基本使用🚗模拟实现 四个方面来一一介绍

1.求字符串长度

1-1strlen求串长

  • 全称:string length
  • strlen函数返回的是字符串函数’\0’前面出现的字符个数,也就是可见长度,或者是有效长度
  • 函数的返回值是size_t是无符号的(易错)

函数原型:size_t strlen(const char* str)

基本使用:

int main()
{
  char arr1[] = "hello world";//[hello world\0]
  //char arr2[]={'h',\0','t'};//必须带有'\0',否则长度未知('\0'出现的位置随机)
  int len = strlen(arr1);
  printf("%d\n", len);
  return 0;
}

易错知识:size_t(坑坑坑):–错误代码示例

int main()
{
  char* p1 = "abc";
  char* p2 = "abcdef";
  if (strlen(p1) - strlen(p2) > 0)//关键点
  {
    printf("haha\n");
  }
  else
  {
    printf("hehe\n");
  }
  return 0;
}

我就不买关子;答案:haha


原因:(算术转换)

两个无符号整型相减得到-3,但是-3在内存读取的时候是以无符号数来看待,所以"符号位"的1其实把他变成了一个很大的数.(两个无符号整数相减还是一个无符号整型)


解决办法:

1.写成if( strlen(p1)>strlen(p2) )的形式

2.强制转换为if( (int)strlen(p1)-(int)strlen(p2) )的形式


模拟实现:

此函数我有专门讲过,欲知速戳三种方法模拟实现strlen函数


2.长度不受限的字符串函数

2-1strcpy拷贝

  • 源字符串必须以’\0’结束
  • 会将源字符串中的’\0’拷贝到目标空间中

目标空间必须足够大,以确保能存放源字符串

目标空间必须可变

函数原型:char* strcpy(char* dest,const char* src)


dest, 全称:destination,-指向用于存储复制内容的目标数组

src,全称:source, -指向要复制的字符串

dest,src的左右位置,也正符合左值空间,右值内容

基本使用 :

int main()
{
  char arr1[30] ="XXXXXXXXX";//1.arr[]是通过直接将字符串放到arr[]这块内存中 2.不能省30且目标空间足以容纳源空间hello
  char* str = "hello";//字符指针str通过指向的是hello这块常量字符串
  //char arr2[]={'h','e','l','\0','o'};正确
  //char arr2[]={'h','e','l','l','o'};错误(没有遇到'\0',越界访问,停不下来)
  printf("%s\n", strcpy(arr, str));//1.返回char*类型的dest空间的起始地址  2.链式访问
}

运行结果:

8f3be2b2fadd443b8cc4ecb8574d8630.png

简单图解:

00af3e4f491c45379d2d30b48e3a391f.png

模拟实现:

d7d603aa534e4c5fb3d957af7e9aa49d.png

优化一下:

char* my_strcpy(char* dest, const char* src)
{
    assert(dest&&src);
  char* ret = dest;//ret保存dest的初始位置(后面dest会移动)
  while (*dest++=*src++);//1.赋值    2.++
  return ret;
}


2-2strcat追加

  • 源字符串必须以’\0’结束
  • 会将源字符串中的’\0’拷贝到目标空间中(追加完的字符串的’\0’是源字符串的)
  • 目标空间必须足够大,以确保能存放源字符串
  • 目标空间必须可变(也就是目标空间必须是字符数组,不能是指针指向的常量字符串)

函数原型:char* strcat(char* dest,const char* src)

基本使用:

int main()
{
  char arr1[30] = "hello ";
  char arr2[] = "world";
  printf("%s\n", strcat(arr1, arr2));
  return 0;
}

运行结果:

80744df1153c4946aadfe812357e486d.png


简单图解:

6e80ebb812d94fab9910f6b84fe187cb.png

易错知识:(不能给自己追加)–错误代码示例

printf("%s\n",strcat(arr1,arr2);//自己给自己追加


原因:在找到dest的‘\0’后,进行src的的一个字符的拷贝时将dest(其实也是src)的’\0’覆盖掉,追加将无法停下来

模拟实现

char* my_strcat(char* dest, const char* src)//1.能否被修改决定了是否加const  2.const修饰更安全
{
    assert(dest&&src);
  char* ret = dest;
  while (*dest)//1.找目的地空间的'\0'  2.*dest是*dest!='\0'的简化版
  {
    dest++;
  }
  while (*dest++ = *src++);//将src的内容拷贝得到dest中
  return ret;
}

关于我的一点小理解:模拟strcat=模拟strlen+模拟strcpy

这样理解灵感:模拟strcat的两个步骤

2-3strcmp比较

  • 对应比较字符的ASCII值(小写l比大写L的ASCII大)8e3abaf9eaf84acdaad1680d3415281e.png
  • 若arr1>arr2,返回正数;
  • 若arr1==arr2,返回0;
  • 若arr1<arr2,返回负数;

函数原型:int strcmp(const char* str1,const char* str2)

基本使用:

int main()
{
  char arr1[10] = "hello";
  char arr2[10] = "heLLO";
  int ret = strcmp(arr1, arr2);
  if (ret > 0)//VS才固定返回1,0,-1,为增加代码可移植性(通用性),不建议采用1,0,-1的方式
  {
    printf("arr1>arr2\n");
  }
  else if (ret == 0)
  {
    printf("arr1==arr2\n");
  }
  else
  {
    printf("arr1<arr2\n");
  }
  return 0;
}

运行结果:

4175a63f6f574bd780516b52ea03782e.png

模拟实现:

//版本1:
int my_strcmp(const char* str1, const char* str2)
{
  while (*str1 && *str1++ == *str2++);//**在遇到\0之前都相等就一直比下去**
  return *--str1 - *--str2;
}
//版本2:
int my_strcmp(const char* str1, const char* str2)
{
    assert(str1&&str2);
  int ret = 0;
  while (!(ret = (*str1++) - (*str2++)) && (*str1));//妙不可言
  return ret;
}
目录
相关文章
|
10天前
10分钟让你学会内存函数:memcpy,memmove,memset,memcmp的用法及模拟实现。
10分钟让你学会内存函数:memcpy,memmove,memset,memcmp的用法及模拟实现。
12 2
|
6天前
|
C语言
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
16 0
|
10天前
|
C语言
字符串和内存函数(1)
字符串和内存函数(1)
25 7
|
6天前
|
C语言
【C语言】:4大内存函数
【C语言】:4大内存函数
10 2
|
10天前
字符串和内存函数(2)
字符串和内存函数(2)
23 5
|
16天前
|
安全 C语言
【C语言基础】:内存操作函数
【C语言基础】:内存操作函数
|
3天前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
11 0
|
3天前
|
程序员 C语言
C语言内存管理:malloc、calloc、realloc与free函数详解
C语言内存管理:malloc、calloc、realloc与free函数详解
5 0
|
7天前
|
C语言
C语言内存函数
C语言内存函数
8 0
|
9天前
|
C语言 C++
C语言----C语言内存函数
C语言----C语言内存函数
10 0