当前课程知识点:高级语言程序设计 > 字符串 > 8.3 自定义字符串处理函数 > 自定义字符串处理函数
大家好
本讲我们来介绍如何自定义字符串处理函数
前面介绍了几种常用的系统字符串处理函数
应当再次强调
系统库函数并非C语言本身的组成部分
而是人们为使用方便
而编写的公共函数
字符串是一种常见的数据类型
在实际开发
尤其是非数值处理中
字符串的应用非常广泛
虽然很多字符串操作都封装在函数库里
应用程序可以直接通过调用库函数
来实现字符串操作
然而对于开发者而言
若能了解其底层实现原理
对于编程能力的提高是很有好处的
下面介绍几种常用的
字符串处理函数的实现原理
自定义字符串处理函数时
既可使用字符数组作为函数形参
也可使用字符指针作函数的形参
调用自定义字符串处理函数时
向函数传递字符串的首地址
由于字符串本身带有特定的结束标志
不需要传递字符串的长度
对比以前学过的
如果自定义函数的形参是数值型数组的话
比如说int型数组
float型数组
一般还需要定义一个整型形参
用来接收数组的长度
首先来看如何自定义计算字符串长度的函数
我们先用字符数组来实现这个函数
也就是将这个函数的形参定义为字符数组
我们首先要设置一个计数器变量len
并且将len初始化为零
然后用一个循环来依次查找
字符串中的每一个字符
看它是否是字符串结束标志
如果不是字符串结束标志
就将len+1
当查到最后一个字符
是字符串结束标志的时候
就退出这个循环
然后将len的值返回
len的值实际上就是字符串中
不包含字符串结束标志的实际字符的个数
下面我们再来看
如何用字符指针来实现这个函数
这个时候呢
函数形参就改为字符指针变量
在函数内部
同样用len来记录字符串中实际字符的个数
只不过原来是用下标
来遍历数组中的每一个元素的
现在呢
可以用指针来指向字符串中的每一个字符
如果发现指针指向的字符
是字符串结束标志的时候
这个循环就结束了
返回len的值
自定义函数的形参是一维数组时
编译器也是将它解释为一个指针变量的
所以这两种写法是等价的
下面呢
我们可以在函数形参数组
或形参指针类型的前面
加一个const类型的修饰符
加上const类型修饰符的作用
就是保护指针变量指向的内容
不被这个函数所修改
也就是说
如果你不希望这个函数
来改变这个字符串的内容的话
那么就可以在声明形参数组
或指针变量的时候
加上const类型修饰符
这样一旦在这个函数体中
改变了这个指针变量
指向的字符串的内容
那么编译器就会报警
由于这个mystrlen函数
只是计算字符串中的实际字符的个数
并不需要修改字符串的内容
所以我们在形参前加上const类型修饰符
来看完整的程序
这是主函数
这是自定义的求字符串长度的函数
在主函数里以%d的格式
输出自定义函数的返回值
这是调用语句
向被调函数传递一个实参
mystrlen函数的形参前
加上一个const类型修饰符
确保实参字符串a的值
不被mystrlen函数所修改
下面我们再来看
如何自定义字符串复制函数
定义mystrcpy这个函数的时候
这个函数有两个形参
第二个形参数组strsrc
存放的是要复制的字符串
第一个形参数组strdest
指定了字符串复制的目标位置
我们设计的mystrcpy这个函数没有返回值
因此返回值类型为void
在函数体内进行字符串复制的操作
我们要编写这样的一个循环语句
用下标值的变化
来指向数组中的每一个字符
来完成字符的复制
首先i等于0的时候
在下标为0的数组元素
不等于空字符时
将源字符数组strsrc中的第一个字符
复制到目标字符数组strdest中
然后将i的值加一
当对应的源字符数组中的字符
不等于字符串结束标志的时候
拷贝到目标数组中
i的值再加一
后面的依次类推
当取出的字符
等于字符串结束标志的时候呢
这个条件为假
就退出了这个循环
退出这个循环
就没有执行循环体中的语句
也就是没有执行这个赋值的操作
因此这个时候
目标字符数组中的最后一个字符
不是字符串结束标志
还不能当做一个字符串来处理
所以呢
在退出循环以后
还要执行这样的一条语句
单独将字符串结束标志
复制给当前的这个下标位置
我们还可以用字符指针
来编程实现这个函数
形参改为了指针变量
在函数体内语句可以不变
也可以改成通过两个指针变量
访问指向的字符串
在每次执行循环体之前判断
源字符指针指向的字符
是否是字符串结束标志
只要它不是字符串结束标志
那么就执行循环体中的语句
并且将第二个形参
加上一个const的类型修饰符
因为第二个形参
也就是这个源字符指针
指向的字符串是不需要被修改的
所以呢
我们用const来保护它指向的字符串的内容
来看例2
使用我们自定义的字符串拷贝函数
调用mystrcpy函数时
第2个实参可以是字符数组
也可以是字符串常量
第1个实参必须是字符数组
我们设计的strcpy函数是没有返回值的
但事实上标准C提供的库函数
strcpy和strcat是有返回值的
它们的返回值就是指向字符串的指针
那么为什么还要从函数
返回指向字符串的指针呢
这是因为
如果函数能够返回指向字符串的指针的话
那么就可以将这个函数调用
放到一个表达式中了
放到表达式中的好处呢
就是可以以级联的形式
来实现多个字符串的连续复制
或者以级联的形式
来实现多个字符串的连续连接
例如先将字符串str1与"hello China "连接
再求字符串str1的长度
我们用了两个表达式完成
那么用级联的方式呢
用一个表达式就可以实现同样的功能
现在我们希望自定义的字符串连接函数
能够像这样调用
这两条语句的功能
可以用下面一条语句来实现
自定义一个字符串连接函数
让它的函数返回值
是一个指向字符串的指针
这个函数的形参有两个
一个是指向源字符串strsrc的指针
一个是指向目的字符串strdest的指针
由于我们要将源字符串
连接到目的字符串的后面
也就是从目的字符串的字符串结束标志
这个位置开始进行连接
所以第一步
我们要编写这样的一个循环语句来实现
将目的字符串的指针
移到字符串结束标志这个位置
定位到这个位置之后呢
我们再进行字符串复制的操作
再用一个循环语句
将源字符串strsrc指向的字符串
复制到目的字符串strdest指向的位置
注意
在退出这个循环之后
我们还要用这个赋值语句
将字符串结束标志
添加到连接后的字符串末尾
这里需要注意的一点就是
因为在实现字符复制的过程中了
没有进行边界检查
所以应该保证这个目的字符串的空间足够大
以便能够容纳得下
连接后的这个字符串的内容
最后返回指向目的字符串的指针strdest
来看例3
使用我们自定义的字符串连接函数
在编写主函数的时候
要定义两个数组
Strdest这个数组要定义得足够大
以便能够容纳得下连接后的字符串
然后让用户分别从键盘输入
第一个字符串和第二个字符串
然后直接调用printf语句
用%s的格式输出
这两个字符串连接后的那个字符串
实现了级联操作
下面我们来小结一下
自定义字符串处理函数
要考虑如何向函数传递字符串
如何从字符串返回字符指针实现链式操作
好了 这是我们这一节的内容
谢谢大家
-1.1 计算机程序和计算机语言
-1.2 C程序的构成
--C程序的构成
-1.3 C语言编辑、编译、运行(VC++2010学习版)
-练习题
-2.1 变量的定义和使用
--变量的定义和使用
-2.2 数据类型
--数据类型简介
--整型数据
--实型数据
-2.3 格式输出和格式输入
-2.4 运算符和表达式
--运算符和表达式
-2.5 结构化程序设计入门
-练习题
-3.1 为什么要用选择结构解决问题
-3.2 如何正确表示选择结构中的条件
-3.3 用if语句及if语句嵌套实现选择结构
-3.4 用switch语句实现选择结构
-练习
-4.1 循环的引入
-4.1 循环的引入--作业
-4.2 用while语句实现循环
-4.3 用do-while语句实现循环
-4.4 用for语句实现循环
-- 用for语句实现循环
-4.4 用for语句实现循环--作业
-4.5 何时需要用循环的嵌套
-4.6 如何提前终止循环和提前结束本次循环
-习题--作业
-5.1 数组类型的引入
--数组类型的引入
-5.2 一维数组的定义和初始化
-5.3 一维数组的使用
--一维数组的使用
-5.4 二维数组的定义和初始化
-5.5 二维数组的使用
--二维数组的使用
-习题--作业
-6.1 什么是指针
--什么是指针
-6.2 指针类型及相关概念
-6.3 指针变量的定义、赋值与使用
-6.4 指针的运算
--指针的运算
-6.5 指针与一维数组
--指针与一维数组
-6.6 指针的指针
--指针的指针
-6.7 指针与二维数组
--指针与二维数组
-习题--作业
-7.1 为什么要自定义函数
-7.2 函数的定义
--函数的定义
-7.3 函数的调用
--函数的调用
-7.4 函数参数的传递
--函数参数的传递
-7.5 函数的嵌套调用和递归调用
-7.6 变量的作用域和存储类型
-习题--作业
-8.1 字符串的存储及输入输出
-8.2 系统字符串处理函数
-8.3 自定义字符串处理函数
-习题--作业
-9.1 结构体类型的定义
--结构体类型的定义
-9.2 结构体变量及指针变量的定义及使用
-9.3 结构体变量和指针变量作函数的参数
-9.4 结构体数组的定义和使用
-9.5 共用体类型和枚举类型
--共用体和枚举类型
-习题--作业
-动态内存分配--习题
-习题--作业