进阶C语言——字符串和内存函数(上)

简介: 进阶C语言——字符串和内存函数

今天我们学点库函数

字符函数和字符串函数

字符串长度函数->strlen

strlen需要的头文件是string.h ,那它的作用是什么呢??

他是来求字符串长度的,统计的是’\0’前的字符串长度

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcdef";
  size_t len = strlen(arr1);
  printf("%d", len);
  return 0;
}

size_t是无符号的意思

学会了strlen函数怎么使用,那我们现在模拟实现一下strlen

之前讲过三种方式来实现,大家是否还记得呢?分别是计数的方式,函数递归的方式,还有我们的指针

计数器的方式

#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* arr)
{
  assert(*arr);
  int count = 0;
  while (*arr++)
  {
    count++;
  }
  return count;
}
int main()
{
  char arr[] = "abcdef";
  size_t len = my_strlen(arr);
  printf("%d\n", len);
  return 0;
}

函数递归

#include<stdio.h>
size_t my_strlen(const char* arr)
{
  if (*arr != 0)
  {
    return 1 + my_strlen(arr + 1);
  }
}
int main()
{
  char arr[] = "abcdef";
  size_t len = my_strlen(arr);
  printf("%d\n", len);
  return 0;
}

指针运算

#include<stdio.h>
int my_strlen(char* arr)
{
  char* str = arr;
  while (*arr)
  {
    arr++;
  }
  return arr - str;
}
int main()
{
  char arr[] = "abcdef";
  int len = my_strlen(arr);
  printf("%d\n", len);
  return 0;
}

strcpy函数

strcpy的作用是把我们的后面字符拷贝到前面字符,但是我们也有相应的前提

源字符串必须以 ‘\0’ 结束。

会将源字符串中的 ‘\0’ 拷贝到目标空间。

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

目标空间必须可变。

那我们用代码来看看效果吧

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcdef";
  char arr2[] = "xxx";
  printf("%s", strcpy(arr1, arr2));
  return 0;
}

我们可以看到其实我们在拷贝的时候,把’\0‘也拷贝进去,下面再给大家看一个特殊例子

观察到我们拷贝的时候,是\0之前,这也符合我们上面的规定

现在我们写一个函数来模拟实现这个效果吧

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
  assert(*dest && *src);
  char* ret = dest;
    while (*dest++ = *src++)
    {
      ;
    }
    return dest;
}
int main()
{
  char arr1[] = "xxxxx";
  char arr2[] = "abcd";
  char* arr3 = my_strcpy(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

我们只是模拟实现,不可能实现vs中的strcpy的功能,比如上面我们的代码缺陷就是不能自己copy自己,会存在覆盖现象,导致不能达到我们想要的效果

stract

源字符串必须以 ‘\0’ 结束。

目标空间必须有足够的大,能容纳下源字符串的内容。

目标空间必须可修改。

这是一个追加的字符串,比如我们要想在arr1字符串后面追加一个hello,这样就可以用我们的strcat

我们用代码看一下它该怎么使用

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "hello";
  char arr2[] = " CSDN";
  char* ret = strcat(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

那我们接下来就是模拟实现函数

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* str)
{
  assert(*dest && *str);
  char* ret = dest;
  while (*++dest)
  {
    ;
  }
  while (*dest++ = *str++ )
  {
    ;
  }
  return ret;
}
int main()
{
  char arr1[] = "hello";
  char arr2[] = " CSDN";
  char* ret = my_strcat(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

strcmp

这是一个比较字符串的函数,但是大家可不要误以为是比较长度的,它的作用是比较ASCII的,一个字符一个字符进行比较

第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串等于第二个字符串,则返回0

第一个字符串小于第二个字符串,则返回小于0的数字

所以我们的strcmp函数的返回值应该是整型

下面我们就写个代码看看效果吧

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcde";
  char arr2[] = "abcdq";
  int len = strcmp(arr1, arr2);
  printf("%d", len);
  return 0;
}

那我们也来模拟实现一下strcmp

#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* dest, const char* str)
{
  assert(*dest && *str);
  while (*dest == *str && *dest && *str)
  {
    dest++;
    str++;
  }
  if (dest==NULL)
  {
    return 0;
  }
  return *dest - *str;
}
int main()
{
  char arr1[] = "abcde";
  char arr2[] = "abcdq";
  int len = my_strcmp(arr1, arr2);
  printf("%d", len);
  return 0;
}

strstr

#include <stdio.h>
#include <string.h>
int main()
{
  char str[] = "This is a simple string";
  char* pch;
  pch = strstr(str, "simple");
  if (pch == NULL)
  {
    printf("找不到\n");
  }
  else
  {
    printf("找到了\n");
  }
  return 0;
}

模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* dest, const char* str)
{
  assert(dest && str);
  char* s1 = dest;
  char* s2 = str;
  char* cul = dest;
  while (*cul)
  {
    s1 = cul;
    s2 = str;
    while (*s1 == *s2)
    {
      s1++;
      s2++;
      if (*s2)
      {
        return cul;
      }
    }
    cul++;
  }
  return NULL;
}
int main()
{
  char str[] = "This is a simple string";
  char arr[] = "simple";
  char* p = my_strstr(str, arr);
  if (p == NULL)
  {
    printf("找不到\n");
  }
  else
  {
    printf("找到了\n");
  }
  return 0;
}

strstr最大作用就是找这个里面有没有我们想要的字符串,如果有就返回查找字符串内该字符串的地址,如果没有就返回空指针


相关文章
|
5天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
32 12
|
3天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
12天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
28 6
|
26天前
|
C语言
【c语言】动态内存管理
本文介绍了C语言中的动态内存管理,包括其必要性及相关的四个函数:`malloc`、``calloc``、`realloc`和`free`。`malloc`用于申请内存,`calloc`申请并初始化内存,`realloc`调整内存大小,`free`释放内存。文章还列举了常见的动态内存管理错误,如空指针解引用、越界访问、错误释放等,并提供了示例代码帮助理解。
38 3
|
25天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
28天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
24 0
|
28天前
|
C语言
【c语言】qsort函数及泛型冒泡排序的模拟实现
本文介绍了C语言中的`qsort`函数及其背后的回调函数概念。`qsort`函数用于对任意类型的数据进行排序,其核心在于通过函数指针调用用户自定义的比较函数。文章还详细讲解了如何实现一个泛型冒泡排序,包括比较函数、交换函数和排序函数的编写,并展示了完整的代码示例。最后,通过实际运行验证了排序的正确性,展示了泛型编程的优势。
20 0
|
6月前
|
存储 编译器 C语言
在C语言中的数组和字符串
在C语言中的数组和字符串
|
2月前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
4月前
|
安全 C语言
C语言8 数组与字符串
C语言8 数组与字符串
34 0