进阶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最大作用就是找这个里面有没有我们想要的字符串,如果有就返回查找字符串内该字符串的地址,如果没有就返回空指针


相关文章
|
1月前
|
存储 C语言
`scanf`是C语言中用于按格式读取标准输入的函数
`scanf`是C语言中用于按格式读取标准输入的函数,通过格式字符串解析输入并存入指定变量。需注意输入格式严格匹配,并建议检查返回值以确保读取成功,提升程序健壮性。
728 0
|
3月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
257 15
|
8月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的函数
本文介绍C语言函数:函数是程序模块化的工具,由函数头和函数体组成,涵盖定义、调用、参数传递及声明等内容。值传递确保实参不受影响,函数声明增强代码可读性。君志所向,一往无前!
230 1
一文彻底搞清楚C语言的函数
|
9月前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
220 3
|
3月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
999 0
|
3月前
|
存储 缓存 NoSQL
内存管理基础:数据结构的存储方式
数据结构在内存中的存储方式主要包括连续存储、链式存储、索引存储和散列存储。连续存储如数组,数据元素按顺序连续存放,访问速度快但扩展性差;链式存储如链表,通过指针连接分散的节点,便于插入删除但访问效率低;索引存储通过索引表提高查找效率,常用于数据库系统;散列存储如哈希表,通过哈希函数实现快速存取,但需处理冲突。不同场景下应根据访问模式、数据规模和操作频率选择合适的存储结构,甚至结合多种方式以达到最优性能。掌握这些存储机制是构建高效程序和理解高级数据结构的基础。
297 0
|
3月前
|
存储 弹性计算 固态存储
阿里云服务器配置费用整理,支持一万人CPU内存、公网带宽和存储IO性能全解析
要支撑1万人在线流量,需选择阿里云企业级ECS服务器,如通用型g系列、高主频型hf系列或通用算力型u1实例,配置如16核64G及以上,搭配高带宽与SSD/ESSD云盘,费用约数千元每月。
293 0
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
863 0