首页 > 系统相关 >字符串与内存函数(1)

字符串与内存函数(1)

时间:2023-02-07 22:00:31浏览次数:54  
标签:const 函数 strcat char 内存 字符串 strlen

本篇文章和大家分享一些处理字符和字符串的函数,以及一些内存操作函数。大致有以下几个函数: strlen函数,  strcpy函数,  strcat函数,  strcmp函数 , strncpy函数, strncat函数, strncmp函数, strstr函数和 strtok函数废话不多说,进入正题。

首先,我们讲的是strlen.

strlen

size_t strlen (const char*str);

strlen是一个求字符串长度的函数,参数只有一个,那就是需要操作的字符串的首元素地址。让我们走近代码中看看:

strlen的使用

#include<stdio.h>
int main()
{\\先定义一个字符数组。
char arr[]="casca";
\\再定义一个整型变量,用来接收strlen的返回值。
int len;
\\最后是用strlen函数求出,字符串的长度,保存在变量len中。
len=strlen(arr);//数组名为首元素的地址
return 0;
}

讲完strlen的使用,我们还需要了解使用strlen的一些注意事项。

注意事项

第一点:

strlen的计算以‘\0’作为结束标志,计算‘\0’之前的字符个数(不包含‘\0’)

第二点:

计算的字符串必须以‘\0’作为结束标志

第三点:

strlen返回值的类型size_t是无符号的(易错)

让我看看以下这串代码:

#include<stdio.h>
#include<string.h>
int main()
{
if(strlen("abc")-strlen("cskjdc")>0)
printf(">");
else
printf("<");
return 0;
}
//按数学的角度,3-6=-3,小于零,输出<.
//但实际输出的是>,为什么呢?strlen的返回值
//是size_t无符号整型,所以,系统认为,无符号整型
//减去无符号整型的得到的还是无符号整型,所以,计算
//结果为3大于零,输出>

了解注意事项后,我们对strlen有了更深的了解,接下来,让我们学习一下对strlen的模拟。

strlen的模拟

思路

strlen以’\0‘作为结束标志。所以,我们可以把’/0‘作为一个结束标志,然后,用一个变量来统计之前出现的字符个数,进而实现字符串的统计。好了,理解了模拟的一个思路后,我们进入对strlen的一个模拟。

模拟实现

//首先,参照strlen的基本形式,给出一个我们的strlen的返回值及参数
size_t my_strlen(const char*str)
{
int count=0;//第一步,定义一个变量,记录字符的个数,并初始化为0
while(*str++)//第二步,统计字符数量,*的优先级低,但我们是后置++,
{ //所以,先解引用.当解引用为‘\0’,它的ASCll码值为0,
count++; //停止循环
}
return count;
}
//除了使用循环的方法,我们递归和指针减去指针的方法
//递归
size_t my_strlen(const char*str)
{
if(*str=='\0')
return 0;
else
return my_strlen(str+1)+1;

//指针-指针
size_t my_strlen(const char*str)
{
char*sta=str;
char*end=str;
while(*end)
{
end++;
}
return end-sta;
}

讲到这,strlen我们就基本就学完了。接下来,我们学下一个函数strcpy

strcpy

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

strcpy是一个字符串拷贝函数。可以将一个地址的字符串拷贝到另一个地址。它的第一个参数是目标空间地址,第二个参数是拷贝的源头地址。让我们走近代码去看看:

strcpy的使用

#include<stdio.h>
#include<string.h>
int main()
{
//首先,定义两个字符数组
char arr1[20]={0};
char arr2[]="hello";
//调用strcpy将数组arr2内容拷贝到数组arr1中
strcpy(arr1,arr2);
//这时,打印数组arr1就会输出hello
printf("%s",arr1)
}

了解完了strcpy的使用,让我们再了解一下strcpy的一些注意事项。

注意事项

一:源字符串必须以’\0'作为结束标志

二:源字符串的’\0‘也会被拷贝

三:目标空间要足够大,足以容纳源字符串的内容

四:目标空间必须可变

好了,了解完strcpy的注意事项,我们进行下一步,对strcpy实现模拟。

strcpy的模拟

思路

strcpy的工作原理,是将一个字符串包括结束标志’0‘从一个地方复制到另一个地方去。所以呢?我们模拟strcpy,其实就是,模拟一个复制过程。将字符串一 一复制到目标空间。好了,有了思路,那我们进入对strcpy的模拟实现

模拟实现

//首先参照strcpy的形式,设返回值和形参
char*my_strcpy(char*des,const char*sce)
{
char*ret=des;//返回值是目标空间的地址,用一个变量来储存
while(*des++=*sce++)//进行拷贝,当*sce='\0'时,该表达式为0,结束循环
{
;
}
return ret;
}

strcpy的知识大概就这些了,让我们进入下一个函数的学习吧!

strcat

char*strcat(char*destination,const char*source)

strcat是一个链接两个字符串的函数。它的第一个参数是追加字符串的字符串地址,第二个参数是追加内容的地址。如何使用,让我们走进代码中看看。

strcat的使用

#include<stdio.h>
int main()
{//首先,定义两个字符数组,用两个字符串分别初始化
char arr1[20]="hello ";
char arr2[]="lihua";
//利用strcat将lihua链接到hello 的后面
strcat(arr1,arr2);
//以字符串输出数组arr1,便得到了hello lihua
printf("%s",arr1);

return 0;
}

好了,说完strcat的使用,我们说说strcat的一些注意事项。

注意事项

一:源字符串和要追加的字符串末尾都必须包含结束标志'\0'

二:目标空间必须有足够的空间,容纳追加的字符串

三:目标空间必须可改

四:strcat在自己给自己追加时,会出现bug,追加的时候,会把'\0'

干掉,无法结束。

说完注意事项,我们对strcat有了更深的了解,接下来,我们实现一个对strcat的模拟

strcat的模拟

思路

我们已经知道,strcat是一个字符串追加一个·字符串的函数。它的追加,其实就是复制。只不过,是从字符串末尾开始复制。那它是怎么知道在那追加的呢?这是不是需要一个标志,来进行识别。strcat是通过’\0‘来找到字符串末尾的,所以,我们可以通过’\0‘来找到字符串的末尾,再进行复制,进而实现追加的功能。好了,有了思路,让我们进入对strcat的模拟

模拟实现

//首先,参照strcat,设置返回值及参数
char*my_strcat(char*des,const char*sce)
{
char*ret=des;//定义一个变量,保存目标空间的初始地址
//找到需要追加的字符串的'\0'
while(*des)
{
des++;
}
//进行追加
while(*des++=*sce++)
{
;
}
return ret;
}

接下来,我们介绍strcmp

strcmp

strcmp的使用

int strcmp(const char*str1,const char*str2)

strcmp是一个字符串比较函数.它的两个参数都是字符型地址。让我们走进代码中看看如何使用。

//首先,随便定义两个字符数组
char arr[]="cacsa";
char arr2[]="csvcs";
//调用strcmp进行两个字符串的比较,并用一个变量接受函数的返回值
int ret;
ret=strcmp(arr1,arr2);//c语言标准规定,
//返回大于零的数表示arr1>arr2 返回等于零的数表示arr1=arr1
//返回小于零的数表示arr1<arr2

接下来,我们讲讲该函数的一些注意事项

注意事项

一:比较的两个字符串需包含结束标志'\0'

好了,讲完注意事项,我们进行strcmp的模拟实现。

strcmp的模拟实现

思路

strcmp的一个工作的原理是找到两串字符串的第一个不同点,然后,比较它们的ASCII码值。所以,我们需要先找到两串字符串的第一个不同点,然后,对它们的AASCII码值进行比较,返回对应的数值,这样就实行了对两个字符串的比较。好了,有了思路,让我们进入对strcmp的模拟实现

模拟实现

//首先,参照strcmp,设置返回值和参数
int ny_strcmp(const char*str1,const char*str2)
{
//第一步,找到字符不相同的地方,并且要避免两个完全相同的字符串,出现死循环
while(*str1!='\0'&&*str2!='\0'&&*str1==*str2)
{
str1++;
str2++;
}//第二步进行判断
if(*str1>*str2)
return 1;
else if(*str1==*str2)
return 0;
else
return -1;
}

以上我们学习的strcpy、strcat、strcmp三个函数属于长度不受限制字符串函数,什么意思呢?就是它们不管字符串多长,直到遇到斜杠零为止。这一特点容易造成非法访问的风险。所以,后来c语言又提供了长度受限函数strncpy,strncat,strncmp.它们相比前面的三个函数,只是多加了一个参数,其他的不变。

strncpy

char*strncpy(char*destination,const char*source,size_t num)

strncpy相比strcpy多了一个参数num,也就是要拷贝的字符数量。其他的地方使用是基本相同的。不过有一点要注意当要拷贝的数量大于字符串总个数时,会用‘\0’进行补充。什么意思,让我看看代码

strncpy(arr,"jcak",10);
//拷贝的字符串只有四个字符加一个斜杠零,你非要拷贝10个,只能用‘\0’来补充

strncat

char*strncat(char*destination,const char*source,size_t num)

strncat相比strcat也是只多加了一个num参数,其他的地方基本相同,注意追加完后会补加一个'\0'

strncmp

int strncmp(const char*str1,const char*str2,size_t num)

strncmp相比strcmp同样只是多了一个变量num,其他地方基本没什么不同

接下来,我们讲解下一个函数strstr

strstr

const char*strstr(const char*str1,const char* str2);

strstr的使用

strstr是一个字符串查找函数,就是在一串字符串中找另一串字符串。它的参数都是字符型地址。那怎么使用它呢?同样的让我们走进代码中看看。

#include<stdio.h>
#include<string.h>
int main()
{//先定义两个字符数组,并初始化
char arr1[]="dsiijisdc";
char arr2[]="dc";
//调用函数strstr,函数的返回值为字符串"dc"在字符串"dsiijisdc"中第一次
//出现时的地址。
char*p=strstr(arr1,arr2);
//以上函数的返回值就是字符串"dsiijisdc"中第二个元素"d"的地址。
}

理解了完strstr的使用,我们直接进入对strstr的模拟实现,strstr这个函数呢?没什么特别的注意事项。

strstr的模拟

思路

strstr的功能是在一个字符串中找另一个字符串。我们如和去实现这个共功能呢?我们可以一 一去比对,找到了就返回它第一次出现的地址,否则,返回空指针表示没有找到。好了,理解了一个大致的思路,我们进行实操一下

模拟实现

//首先,模拟strstr的形式,设返回值和形参
const char*my_strstr(const char*str1,const char*str2)
{
//首先,定义所需要的变量
const char*s1=NULL;
const char*s2=NULL;
const char*cp=str1;//比较开始的位置
//其次,开始一 一比较
while(*cp)//这样可以当到字符串到末尾时,还未找到对应的字符串,自动结束循环
{
s1=cp;//把比较的初始位置赋给s1,避免丢失
s2=str2;
//防止str2无字符只有’\0‘的情况
if(!*s2)
return str1;
//一 一对比
while(*s1&&*s2&&*s1==*s2)
{
s1++;
s2++;
}
//判断是否相同
if(!*s2)
return cp;
cp++;
}
//如果没找到,返回空指针
return NULL;
}

以上就是strstr的一个模拟实现,接下来,我们讲讲strtok

strtok

char*strtok(char*str,char*sep)

strtok的使用

>sep参数是一个字符串,定义了用作分隔符的字符集合

>第一个参数是一个字符串,它包含了0个或多个sep中的分隔符

>strtok函数会在str中找到下一个标识符(也就是sep中的分隔符),将其将其替换串’\0‘,然后,返回'\0'前面字符串的首元素地址(注:strtok会改变被操作字符串中的内容,所以,往往临时拷贝一份来进行操作)

>第一个参数不为空指针NULL,strtok将在str找到第一个分隔符,并保存第一个分隔符的地址。

>第一个参数为空指针NULL,strtok将从被保存的分隔符地址开始查找下一个分隔符

>如果str中没有更多的分隔符,将返回空指针NULL

了解完概念,我们走进代码中看看

#include<stdio.h>
int main()
{
char str[]="This,is;flower";
char sep[]=",;";
char*ret;
//第一次传str,后面都传空指针
for(ret=strtok(str,sep);ret!=NULL;ret=strtok(NULL,sep))
{
printf("%s ",ret);
}//结果是This is flower
return 0;
}

由于strtok比较复杂,很难实现它的一个模拟,所以,就不扩展strtok的模拟了。

好了,本次分享就到此结束了,不知道我有没有说明白,给予你一点点收获。如果你有所收获,别忘了给我点个赞,这是对我最好的回馈,当然你也可以在评论发表一下你的收获和心得,亦或者指出我的不足之处。如果喜欢我的分享,别忘了给我点关注噢。

标签:const,函数,strcat,char,内存,字符串,strlen
From: https://blog.51cto.com/u_15933803/6042710

相关文章

  • 区分构造函数、拷贝构造函数和赋值函数
    对象不存在,且没用别的对象来初始化它,那么调用构造函数对象不存在,且用别的对象来初始化它,那么调用拷贝构造函数(调用拷贝构造函数来初始化几种情况)1.一个对象以值传递的方......
  • 默认构造函数是什么
    默认构造函数是:在不提供任何构造函数的前提下,编译器生成的一个没有参数,没有内容的构造函数Aa;调用的是无参构造函数。如果存在其他构造函数,编译器不会自动生成默认构造......
  • 10.9始终确保全局变量用的内存空间
    熟悉了汇编语言后,接下来将进人到本章的后半部分。C语言中在函数外部定义的变量称为全局变量,在函数内部定义的变量称为局部变量。全局变量可以参阅源代码的任意部分,而局部......
  • 凸函数
    https://zhuanlan.zhihu.com/p/87485105https://proofwiki.org/wiki/Inverse_of_Strictly_Increasing_Convex_Real_Function_is_Concave......
  • 10.10临时确保局部变量用的内存空间
    为什么局部变量只能在定义该变量的函数内进行参阅呢?这是因为,局部变量是临时保存在寄存器和栈中的。正如本章前半部分讲的那样,函数内部利用的栈,在函数处理完毕后会恢复到初......
  • 10.8函数内部的处理
    接下来,让我们透过执行AddNum函数的源代码部分,来看一下参数的接收、返回值的返回等机制(代码清单10-5)。  ebp寄存器的值在(1)中人栈,在(5)中出栈。这主要是为了把......
  • 【C语言】文件操作函数代码示例。
    ......
  • m对比PSO,WPA,GWPA以及GWO四种优化算法的优化性能,优化目标函数为10个来自CEC2017的标
    1.算法描述        灰狼优化算法(GWO),灵感来自于灰狼.GWO算法模拟了自然界灰狼的领导层级和狩猎机制.四种类型的灰狼,如α,β,δ,w被用来模拟领导阶层。此外,还......
  • 《Vue.js 设计与实现》读书笔记 - 第13章、异步组件与函数式组件
    第13章、异步组件与函数式组件13.1异步组件要解决的问题用户可以简单通过import异步导入组件。<template><component:is="asyncComp"></template><script>ex......
  • 软件测试|什么是Python函数及名称空间?
    Python函数及名称空间函数什么是函数?函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。作用:函数能提高应用的模块性,和代码的重复利用率函数的语法结构def函......