【C语言】字符串函数的介绍一(strlen、strcpy、stract)

简介: 【C语言】字符串函数的介绍一(strlen、strcpy、stract)

前言

这篇文章是对于字符串操作函数、内存函数的比较详细的介绍。

我们都知道,字符串在C语言中使用的特别频繁,但类型里,却没有字符串这种类型,这时,众多的库函数就可以帮助我们灵活地使用字符串了

这篇文章同样适合已经对于字符串有初步了解的朋友,虽然本篇文章会由浅入深的介绍每个函数,并解释出每个函数是如何实现的,但还是建议您有一定的基础。

下图是本篇文章(共两篇)

话不多说,让我们正式开始吧

strlen

介绍

下图是函数的使用:

从a的地址向后,直到访问到\0结束

返回的是\0之前的元素个数

而当字符串中无\0之后,就会一直向后访问,直到遇到\0,

返回的是随机值

模拟实现strlen

共有三种写法,但这里只介绍第一种,对于剩下的两种,我会单独出一篇文章去讲解

#include<string.h>
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)//使用const是为了保证str指向的元素不被改变
{
  assert(str);
  int count = 0;
  while (*str != '\0')//\0的ASCII码值是0,所以此处可以直接写成while(*str)
  {
    count++;
    str++;
  }
  return count;
}
int main()
{
  char arr = "abcdef";
  int len = my_strlen(arr);
  printf("%zd\n", len);
  return 0;
}

小测试

下面代码的运行结果是什么

int main()
{
  if (strlen("abc") - strlen("abcdef") > 0)
  {
    printf("11\n");
  }
  else
  {
    printf("00\n");
  }
  return 0;
}

答案

讲解

size_t strlen( const char * str );

这是strlen函数的定义

它的返回类型是size_t,那么问题肯定就出在这里了

那么接下来就了解一下size_t

我们转到定义之后,会发现size_t就是unsigned int:无符号整型

typedef unsigned __int64 size_t;

那么再回到这道题,

strlen("abc") == 3
strlen("abcdef") == 6
strlen("abc") - strlen("abcdef") == -3

-3 的类型是无符号整型,所以转换成补码是一个很大的数字,所以判断条件为真

提示:使用int或者size_t来定义strlen时,二者都可,

此处库函数返回值之所以定义成size_t类型,是因为数组的长度不可能是负数

size_t表明函数不会返回负数

int则更方便阅读和理解,二者都可以

strcpy

介绍:

strcpy(arr1, arr2);//arr1是目的地地址,arr2是源字符串,arr2必须以‘\0’结尾

把后者指向的内容,拷贝到前者指向的空间里

此处不可以用arr1 = arr2,把地址赋给地址这种操作,很奇怪

拷贝过程

注意:

arr2中的\0也必须要拷贝进arr1,如图:

模拟实现

实现过程

函数传参

实现拷贝
void my_strcpy(char* dest, const char* src)
{
  assert(dest);
  assert(src);
  while (*src)
  {
    *dest++ = *src++;
  }
  *dest = *src;
}
优化拷贝
my_strcpy(char* dest, const char* src)
{
  assert(dest);
  assert(src);
  while (*dest++ = *src++)
  //表达式的结果是*src,而当*src为\0时,先赋值,再判断,判断结果为假,跳出循环,拷贝结束
  {
    ;
  }
}
返回类型

函数定义中,返回类型是char*

char* strcpy(char* destination, const char* source);

我们在函数完成拷贝后,还需要返回s1的首元素地址,来帮助我们找到拷贝之后的字符串,所以我们还需要单独创建一个变量来存储数组s1的首元素地址,来确保我们能找到这个数组。

最终代码:

char* my_strcpy(char* dest, const char* src)
//目标地址发生变化,而源头地址不发生变化,
//所以src前使用const,dest不使用const(要保证目标空间可改)
{
  assert(dest);
  assert(src);
  char* ret = dest;
  while (*dest++ = *src++)
  {
    ;
  }
  return ret;
}
int main()
{
  char arr1[] = "abcdefghi";
  char arr2[] = "hello";
  char* ret = my_strcpy(arr1, arr2);
  printf("%s\n", arr1);
}

strcat

函数定义

char* strcat(char* strDestination, const char* strSource);

作用:把arr2追加到arr1里,首先找到arr1中的\0,将其替换成arr2的首元素,之后向后追加,直到追加完\0结束。

错误示例如下:

int main()
{
  char arr1[] = "hello";
  char arr2[] = "world";
  strcat(arr1, arr2);
  return 0;
}

数组arr1空间不够大,直接越界访问,程序报错。

模拟实现

对于my_strcpy函数,需要实现两个功能:

首先需要找到目的字符串(arr1)中的\0

之后进行追加(拷贝)

找\0

while (*dest != '\0')
{
  dest++;
}

追加

while (*dest++ = *src++)
{
  ;
}

返回值

此处返回的仍应该是arr1的首元素地址,以便于我们找到字符串arr1

返回类型就是char*

完整代码

char* my_strcat(char* dest, const char* src)
{
  assert(dest && src);
  char* ret = dest;
  while (*dest != '\0')
  {
    dest++;
  }
  while (*dest++ = *src++)
  {
    ;
  }
  return ret;
}

小技巧

对于部分库函数,我们可以找到他们是如何实现的

具体操作方法如下:

找到对应的路径、找到要查看的头文件,直接用VS运行即可

这里以strcat为例子

这就是我们模拟实现中做的三步:

寻找\0

追加字符串

返回数组首元素地址

结语

因为文章长度,这篇文章只介绍三个函数,下篇文章会继续介绍


相关文章
|
2月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
237 15
|
11月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
172 0
|
11月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
110 0
|
11月前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲
|
11月前
|
C语言
【C语言】模拟实现深入了解:字符串函数
【C语言】模拟实现深入了解:字符串函数
【C语言】一篇就够了(建议收藏)——超详解sizeof与strlen的用法
【C语言】一篇就够了(建议收藏)——超详解sizeof与strlen的用法
【C语言】一篇就够了(建议收藏)——超详解sizeof与strlen的用法
|
8月前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
369 23
|
7月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的函数
本文介绍C语言函数:函数是程序模块化的工具,由函数头和函数体组成,涵盖定义、调用、参数传递及声明等内容。值传递确保实参不受影响,函数声明增强代码可读性。君志所向,一往无前!
177 1
一文彻底搞清楚C语言的函数
|
8月前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
304 15
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
|
8月前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
147 24