C语言进阶学习日志:字符串和内存函数(一)(上)

简介: C语言进阶学习日志:字符串和内存函数(一)

strlen函数

strlen函数 用于求字符串的的长度不包括'\0' 注意strlen函数指向的字符串必须有'\0'结尾

image.png

这个是MSDN的讲解  头文件是<string.h>


模拟strlen函数

模拟strlen函数有三种方法是 计数法 递归法 指针运算法

计数法:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* arr)//因为我们只是去计算一个字符串中的字符个数 并不会通过它的地址改变
{                                来改变它的内容 所以我们这里用 const 表示由arr指针指向的内容
  assert(arr != NULL);        不可改变 当然只是不能由arr来改变
  int count = 0;
  while (*arr!='\0')
  {
    arr++;
    count++;
  }
  return count;
}
int main()
{
  char arr[] = "adsdffafs";
  printf("%d", my_strlen(arr));
  return 0;
}

这里面的assert起的是一个断言的作用 因为我们也不清楚 传进来的地址是否是空地址 所以在学习了指针这一块后 对于传址操作 我们应该更加的敏感 以防出现出现错位 而断言就可以做到这一点 就相当于是一个长官对他手下的命令一样 是不能违背的

他的头文件是 <assert.h>


递归法:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* arr)
{
    assert(arr);
  if (*arr == '\0')
  {
    return 0;
  }
  else
  {
    return 1 + my_strlen(arr + 1);
  }
}
int main()
{
  char arr[] = "adsdffafs";
  printf("%d",my_strlen(arr));
  return 0;
}

递归法的原理就是 我们将arr字符串向后递归直到遇到'\0'返回 0 如果不是则加一向后递归下一个字符并加1 最后,递归一次就会加1 从而返回 字符串的长度


指针运算法:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* arr)
{
  assert(arr != NULL);
  const char* sert = arr;
  while (*arr != '\0')
  {
    arr++;
  }
  return arr - sert;
}
int main()
{
  char arr[] = "adsdffafs";
  printf("%d", my_strlen(arr));
}

要使用这种方法我们要知道指针的运算是怎样的


d80613e52e6541f1921d1ea85507c008.png

指针运算中的减法减出来的 就是这个之前到被减指针中间的元素个数 了解这个特性后 就已经有思路了吧

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* arr)
{
  assert(arr != NULL);
  const char* sert = arr;
  while (*arr != '\0')
  {
    arr++;
  }
  return arr - sert;
}
int main()
{
  char arr[] = "adsdffafs";
  printf("%d", my_strlen(arr));
}

这样我们模拟strlen函数的三种方法就说完了


最后有个这样的问题

 #include <stdio.h>
 int main()
 {
     if( strlen("abc") - strlen("abcdef") > 0)
     {
         printf(">0"); 
     }
     else
     {
         printf("<=0");
     }
 }

大家觉得这个代码最后打印出来的是什么内 注意strlen函数的返回值是一个无符号数哦

如果给他们强制类型转换成 int 会是什么结果内


长度不受限制的字符串函数

  1. strcpy
  2. strcat
  3. strcmp


strcpy函数:

在使用 函数之前要注意这几点

① 源字符串必须以'\0'结尾

② 目标空间必须可变 且足够大来储存拷贝过来的字符串

③ 会将源字符串的'\0'拷进去

de054b5ad8544b7fa68b87cc37a2921c.png

#include <stdio.h>
int main()
{
   char arr[]={1,2,3,4,5,6};//这样的源字符串就是不可取的
   char ret[]="1234567";
   char tmp[]="xxx";
   strcpy(tmp,ret);//像这样也是不可以的 因为目标空间不够
   char ch1[]="1234567";
   char ch2[]="xxx";
   printf("%s", strcpy(ch1,ch2));//链式访问
   //打印出来是xxx因为'\0'也被拷进去了
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* arr, const char* tmp)
{
  char* ret = arr;
  assert(arr && tmp);
  while (*arr++ = *tmp++)//每次赋值完后加加
  {
    ;
  }
  return ret;
}
int main()
{
  char arr1[30] = "asd";
  char arr2[] = "xxxxxx";
  printf("%s",my_strcpy(arr1, arr2));
}

strcat函数:

这个是一个字符串连接函数 就好像"hello" "world" 连接后"helloworld"

其实模拟实现的方法很简单就是找到目标字符串末尾的 ‘\0’ 找到后 重复上面strcpy的步骤

4889884c7b6e48af993aeeaba3d07ed7.png

① 源字符串也是要有 '\0' 的结尾 不然函数不知道从哪里开始追加

②目标空间必须可修改 且足够大来存储追加的字符串

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* tmp, const char* ret)
{
  assert(tmp && ret);
  char* p = tmp;
  while (*tmp != '\0')  不能写成while(*tmp++) 因为在判断到'\0'的时候虽然会跳出循环 但在这之前
  {                     会++一次 跳过末尾的'\0'
    tmp++;
  }
  while (*tmp++ = *ret++)
  {
    ;
  }
  return p;
}
int main()
{
  char arr1[30] = "xxxxxx";
  char arr2[] = "abcd";
  printf("%s",my_strcat(arr1, arr2));
}


strcmp函数:

比较字符串中每个对应位置的字符的ASCLL码值

8199de6fdaaa42a19dc58088b1feaf01.png

要注意的是strcmp函数返回的值是 小于0 等于0 大于0 所以我们在模拟的时候 要注意返回的值不一定就是1,0,-1

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


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2天前
|
C语言
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
|
2天前
|
C语言
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)
|
2天前
|
C语言
(浙大版《C语言程序设计(第3版)》 习题6-5 使用函数验证哥德巴赫猜想 (20分)
(浙大版《C语言程序设计(第3版)》 习题6-5 使用函数验证哥德巴赫猜想 (20分)
|
4天前
|
安全 C语言
【C语言】strcpy与strncpy函数的使用和模拟实现
【C语言】strcpy与strncpy函数的使用和模拟实现
5 0
|
4天前
|
C语言
【C语言】字符分类函数与字符转换函数
【C语言】字符分类函数与字符转换函数
9 1
|
28天前
|
Java
使用Java代码打印log日志
使用Java代码打印log日志
89 1
|
1月前
|
Linux Shell
Linux手动清理Linux脚本日志定时清理日志和log文件执行表达式
Linux手动清理Linux脚本日志定时清理日志和log文件执行表达式
81 1
|
2月前
|
SQL 关系型数据库 MySQL
MySQL数据库,可以使用二进制日志(binary log)进行时间点恢复
对于MySQL数据库,可以使用二进制日志(binary log)进行时间点恢复。二进制日志是MySQL中记录所有数据库更改操作的日志文件。要进行时间点恢复,您需要执行以下步骤: 1. 确保MySQL配置文件中启用了二进制日志功能。在配置文件(通常是my.cnf或my.ini)中找到以下行,并确保没有被注释掉: Copy code log_bin = /path/to/binary/log/file 2. 在需要进行恢复的时间点之前创建一个数据库备份。这将作为恢复的基准。 3. 找到您要恢复到的时间点的二进制日志文件和位置。可以通过执行以下命令来查看当前的二进制日志文件和位
102 1
|
2月前
|
监控 Shell Linux
【Shell 命令集合 系统管理 】Linux 自动轮转(log rotation)日志文件 logrotate命令 使用指南
【Shell 命令集合 系统管理 】Linux 自动轮转(log rotation)日志文件 logrotate命令 使用指南
51 0
|
2月前
|
存储 数据库
ALTER MATERIALIZED VIEW LOG :语句来更改现有物化视图日志的存储特征或类型。
`ALTER MATERIALIZED VIEW LOG` 语句用于修改已有的物化视图日志的存储属性或类型。配合示例中的动画图像(由于格式限制无法显示),该语句帮助优化数据库的性能和管理。
46 0