C语言——详解字符函数和字符串数组(上)

news2024/11/18 22:56:53

目录

一、strlen的使用和模拟实现

1.strlen()函数的介绍

2.strlen()函数的具体使用

3.strlen函数的注意事项

4.strlen函数的模拟实现

二、strcpy的使用和模拟实现

1.strcpy()函数的介绍

2.strcpy()函数的具体使用

3.strcpy()函数的注意事项

4.strcpy函数的模拟实现

三、strcat 的使用和模拟实现 

1.strcat()函数的介绍

2.strcat函数的具体使用

3.strcat函数的注意事项

4.strcat函数的模拟实现

四、strcmp的使用和模拟实现

1.strcmp()函数的介绍

2.strcmp()函数的具体使用

3.strcmp函数的注意事项

4.strcmp函数的模拟实现


一、strlen的使用和模拟实现

1.strlen()函数的介绍

strlen:计算的是字符串str的长度,从字符的首地址开始遍历,以 '\0' 为结束标志,然后将计算的长度返回,计算的长度并不包含'\0'。下面是库中的strlen()函数:

size_t  strlen (const char* str);

  1. 函数的参数为------const char* str:字符指针
  2. 返回值的类型------size_t:无符号整数(即:unsigned int)

前提知识:

  • const关键字:是用来定义常量的,若一个变量被const关键字修饰时,那么这个变量的值就不可以被改变。故:这里的 * str 的值是不能被修改的。
  • size_t数据类型:表示C中任何对象所能达到的最大长度,它是无符号整数。

1.使用const关键字:这里只是计算字符串的长度,用const修饰,避免将原字符串修改掉。

2.使用size_t数据类型:这里返回计算的字符串长度,长度最小值为0,不可能为负数。

2.strlen()函数的具体使用

场景一:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[10] = "abcde";
	int num = strlen(arr);
	printf("数组arr的长度为:%d\n", num);
 
	return 0;
}

输出的结果:

 场景二:

#include <stdio.h>
#include <string.h>
 
int main()
{
	char arr[] = { 'a','b','c','d','e' };
	int num = strlen(arr);
	printf("数组arr的长度:%d\n", num);
 
	return 0;
}

输出的结果:

上述两种场景输出的结果并不相同

为什么会出现这样的结果,我们在用strlen函数时应该注意什么?

3.strlen函数的注意事项

strlen函数:当计算长度时,只有遇到'\0'才会停止计算,同时计算的长度不包含'\0'。

    场景一,arr字符数组中存储的是一个字符串(字符串是以'\0'为结束标志的),那么strlen遍历到字符 'e' 时,再向后遍历,就会遇到'\0',此时strlen停止遍历,返回字符个数:5;

    场景二:字符'a'、'b'、 'c' 、'd' 、'e'五个字符依次存储在arr的字符数组中,并没有存储'\0',所以'e'字符后面存储的内容我们并不知道有什么。而strlen函数只有遇到'\0'时才停止,所以返回的个数是一个随机值。

故:我们使用strlen函数时,应该检查字符数组是否以'\0'为结束标志。

4.strlen函数的模拟实现

方式一:

//计数器⽅式
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

 方式二:

//不能创建临时变量计数器,递归的方式
int my_strlen(const char* str)
{
	assert(str);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

  方式三:

int my_strlen(char* s)
{
	assert(str);
	char* p = s;
	while (*p != ‘\0’)
		p++;
	return p - s;
}

补充知识:assert(断言):是一个宏。

assert 的作用是,将括号中的表达式计算出 ,如果其值为假(即为0),那么它会打印出一条出错信息,然后终止程序的运行。这里的assert是防止指针p指向为NULL。

二、strcpy的使用和模拟实现

1.strcpy()函数的介绍

strcpy()函数:是将一个字符串复制到另一块空间地址中 的函数,‘\0’是停止拷贝的终止条件,同时也会将 '\0' 也复制到目标空间。下面是库中的strcpy()函数声明:

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

函数的参数:

char* destination---------目标字符串的首地址
const char* source------源地址:被复制的字符串的首地址,用const修饰,避免修改掉被拷贝的字符串

函数的返回值类型:

char*:返回的是目标字符串的首地址 

2.strcpy()函数的具体使用

场景一:

#include <stdio.h>
#include <string.h>

int main()
{
	char arr[10] = "########";
	printf("%s\n", strcpy(arr, "hello"));

	return 0;
}

输出的结果: 

场景二: 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main()
{
	char arr1[10] = "**********";
	char arr2[10] = "abcd";
	printf("%s\n", strcpy(arr1, arr2));
	return 0;
}

输出结果:

3.strcpy()函数的注意事项

1.源字符必须以 '\0'结束:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main()
{
	char arr1[10] = "**********";
	char arr2[] = { 'a','b','c','d' };
	printf("%s\n", strcpy(arr1,arr2));
 
	return 0;
}

这里的代码会出错,'\0'是停止拷贝的终止条件,arr2字符数组所在的内存空间后面存储的内容并不知道,不遇到 '\0' 拷贝就不会停止,这就会导致越界访问,程序就会出现问题。 

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

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

这里虽然拷贝成功并将结果输出了,但程序却崩溃了。目标空间太小,不足以放置拷贝的源字符串,会造成溢出的情况 

3.目标空间必须可变

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main()
{
	char* str1 = "hello world";
	char str2[10] = "*********";
	printf("%s\n", strcpy(str1,str2));
 
	return 0;
}

这里的程序也出现了错误。str1指向的是常量字符串,是不可以被修改掉的,目标空间必须是可以被修改的,因为要将拷贝的字符串放在目标空间中。而源字符串可以是能够修改的,也可以是不能修改的,因为strcpy函数的第二个参数已经用const关键字修饰了,保证了拷贝过程中不会被修改。 

4.strcpy函数的模拟实现
char *my_strcpy(char *dest, const char*src)
{ 
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 
 while((*dest++ = *src++))
 {
    ;
 }
 return ret;
}

三、strcat 的使用和模拟实现 

1.strcat()函数的介绍

strcat的函数原型的声明为:

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

其返回值为char*,需要传入两个参数

strcat函数可以将一个字符串追加到另外一个字符串的后面

2.strcat函数的具体使用

比如在“hello”后面追加一段“world”就可以用strcat函数来实现

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[30] = "hello ";
	char arr2[] = "world";
	strcat(arr1, arr2);
	printf("%s\n", arr1);//追加字符串
    return 0;
}

 打印结果:

3.strcat函数的注意事项

• 源字符串必须以 '\0' 结束。

• 目标字符串中也得有 \0 ,否则没办法知道追加从哪里开始。

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

• 目标空间必须可修改。

• 字符串自己给自己追加,如何?

自己给自己追加

char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	//1. 找到目标空间的\0
	while (*dest)
	{
		dest++;
	}
	//2. 拷贝
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[20] = "hello ";
	my_strcat(arr1, arr1);
	printf("%s\n", arr1);
	return 0;
}

这样会一直追加下去,并且会造成访问越界。

4.strcat函数的模拟实现
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest)
	{
		dest++;
	}
	while ((*dest++ = *src++))
	{
		;
	}
	return ret;
}

四、strcmp的使用和模拟实现

1.strcmp()函数的介绍

strcmp函数是C语言中的字符串比较函数,用于比较两个字符串的大小。

函数原型:

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

  • 该函数接受两个参数,分别为要比较的两个字符串的指针。
  • 返回值为整形,表示两个字符串的大小关系。

• 标准规定:

     ◦ 第⼀个字符串大于第⼆个字符串,则返回大于0的数字

     ◦ 第⼀个字符串等于第⼆个字符串,则返回0

     ◦ 第⼀个字符串小于第⼆个字符串,则返回小于0的数字

     ◦ 那么如何判断两个字符串? 比较两个字符串中对应位置上字符ASCII码值的大小。

2.strcmp()函数的具体使用

strcmp函数的比较规则是按照字典序进行比较,即逐个字符比较。具体的比较过程如下:

  1. 若两个字符相等,则继续比较下一个字符。
  2. 若两个字符不相等,则返回它们的ASCII码差值(ASCII码值大的字符串大)。
#include <stdio.h>
#include <string.h>
 
int main()
{
	char str1[] = "appple";
	char str2[] = "banana";
 
	int ret = strcmp(str1, str2);
	if (ret == 0)
		printf("str1和str2相等\n");
	else if (ret > 0)
		printf("str1大于str2\n");
	else
		printf("str1小于str2\n");
		
	return 0;
}

 

3.strcmp函数的注意事项

1、字符串的比较是按照字典序进行的,因此大小写字母的比较结果不同。

2、在比较字符串时,需要确保字符串以'\0'结尾,否则可能会导致比较结果不正确。

例如这个代码:

#include <stdio.h>
#include <string.h>
 
int main()
{
	char str1[] = "hello";
	char str2[] = "hello";
 
	str1[5] = '!';
	int ret = strcmp(str1, str2);
	if (ret == 0)
		printf("str1和str2相等\n");
	else if (ret > 0)
		printf("str1大于str2\n");
	else
		printf("str1小于str2\n");
 
	return 0;
}

 结果如下:

那为什么会这样呢?

分析如下

在这段代码中,我们将str1字符串的结尾标识符'\0'改成了'!',运行代码后,输出结果为"str1大于str2"。这是因为str1字符串没有以'\0'结尾,所以strcmp函数会继续比较下去,直到遇到str2字符串的结尾标识符'\0'。由于str1字符串比str2字符串长,所以str1被认为是大于str2。

4.strcmp函数的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
 
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;//相等
		str1++;
		str2++;
	}
	if (*str1 > *str2)
		return 1;//大于
	else
		return -1;//小于
}
 
int main()
{
	char str1[] = "appple";
	char str2[] = "banana";
 
	int ret = my_strcmp(str1, str2);
	if (ret == 0)
		printf("str1和str2相等\n");
	else if (ret > 0)
		printf("str1大于str2\n");
	else
		printf("str1小于str2\n");
		
	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1389939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js逆向第19例:猿人学第17题天杀的Http2.0

文章目录 一、前言二、定位关键参数三、代码实现四、参考文献一、前言 任务十七:抓取这5页的数字,计算加和并提交结果 题目已经给出来标准答案,而且此题设置为“非常简单”其关键就是HTTP/2.0请求,打开控制台查看请求接口数据如下: 二、定位关键参数 可以看到控制台显示…

计算机毕业设计-----SSH学生请假管理系统

项目介绍 本项目分为管理员、教师、学生三种角色&#xff1b; 教师角色包含以下功能&#xff1a; 教师角色登录,请假查看,审批学生请假,学生管理等功能。 管理员角色包含以下功能&#xff1a; 班级管理,班主任管理,公告管理,留言板管理,学生管理等功能。 学生角色包含以下…

MySQL 中有关 NULL 的三个坑

mysql sum 函数、count 函数&#xff0c;以及 NULL 值条件可能踩的坑。 SELECT SUM(score) FROM person ; nullSELECT COUNT(score) FROM person; 0select id from person where scoreNULL; null 显然&#xff0c;这三条 SQL 语句的执行结果和我们的期望不同&#xf…

一篇文章带你搞懂---全排序

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 全排序&#xff08;Permutation&#xff09;是指将一组元素按照一定的顺序进行排列的过程。在计算机科学中&#xff0c;全排序是一…

Centos系统安全设置

1 设置密码复杂度&#xff0c;帐号密码有效期3个月 密码复杂度要求&#xff1a;最小长度8位&#xff0c;至少2位大写字母&#xff0c;1位小写字母&#xff0c;4位数字&#xff0c;1位特殊字符 1&#xff09;执行备份&#xff1a; #cp -p /etc/login.defs /etc/login.defs_bak…

zotero使用gpt

zotero使用gpt 下载 zotero下载&#xff1a;https://www.zotero.org/download/ 插件下载&#xff1a;https://github.com/MuiseDestiny/zotero-gpt?tabreadme-ov-file 插件安装 zotero中选择 工具->添加组件 选择右上角的齿轮&#xff0c;选择Install add-on from fil…

c++继承和派生(1)

目录 1.含义&#xff1a;从不同层面看的&#xff0c;同一种意思 2. 继承的使用场景 1. 共同之处 2. 迭代更新 3. 代码重构 3. 继承的基本语法 4. 继承了什么 1. 查看占用内存大小 2. 使用vs自带的功能查看类的内存分布 布局&#xff1a; 3. 结果 5. pr…

软件测试|使用Python提取出语句中的人名

简介 在自然语言处理&#xff08;NLP&#xff09;中&#xff0c;提取文本中的人名是一项常见的任务。Python作为一种流行的编程语言&#xff0c;拥有强大的NLP库和工具&#xff0c;使我们能够轻松地进行这项任务。在本文中&#xff0c;我们将使用Python示例来演示如何提取文本…

Linux第23步_安装windows下的STM32CubeProgrammer软件和安装 DFU驱动程序

STM32CubeProgrammer软件是通过USB3.0接口烧写系统软件。 STM32CubeProgrammer需要java运行环境&#xff0c;因此需要安装JAVA软件。 Java 运行环境版本必须是 V1.7 及以上&#xff0c;一定要用 64位的&#xff0c;和win系统一致&#xff0c;否则使用 STM32CubeProgrammer烧…

深入解析JavaScript中的函数绑定和命名函数表达式

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 函数是JavaScript中最重要的组成部分之一。但是函数的this绑定和作用…

Power Query 中常用的数据清洗、转换操作

&#xff08;一&#xff09;数据筛选、保留、删除、去重 1、数据筛选 操作步骤 选中列——点击列名右侧箭头——进行筛选 可选操作 勾选文本筛选器&#xff1a;等于/不等于、开头是/开头不是、结尾是/结尾不是、包含/不包含数字筛选器&#xff1a;等于/不等于、大于/大于等于…

harbor https

harbor https部署 准备docker-compose安装https 证书harbor安装访问harbor推镜像到harbor 准备 192.168.112.99&#xff0c;harbor&#xff0c;centos7 192.168.112.3&#xff0c;测试机&#xff0c;centos7 docker版本&#xff1a;docker-ce 20.10.16&#xff08;部署参考&a…

主流浏览器设置代理IP之搜狗浏览器

给浏览器设置代理IP是目前代理IP的主流使用场景之一&#xff0c;接下来小编就手把手教你如何对搜狗浏览器进行代理IP设置 注&#xff1a;本次使用IP来源于携趣代理平台 搜狗浏览器内设置IP代理 1、首先需要进入浏览器【设置】 2.点击【代理设置】选择【代理服务器设置】然后进…

ITE IT6801FNBX HDMI接收器 芯片

一、物料概述 IT6801FN是一款单端口HDMI接收器&#xff0c;可在HDMI1.4和MHL2.1双模式下工作&#xff0c;完全兼容MHL2.1、HDMI 1.4a、HDMI 1.4a3D和HDCP1.4&#xff0c;还可向后兼容DVI 1.0规格。IT6801FN具有深彩色功能&#xff08;高达36位&#xff09;&#xff0c;可确保接…

腾讯开源AI工具PhotoMaker,无需训练模型就能保持脸部一致随意换装。

腾讯开源AI工具PhotoMaker&#xff0c;无需训练模型就能保持脸部一致随意换装。 最近&#xff0c;AI文本到图像生成领域取得了显著进展&#xff0c;然而&#xff0c;现有的个性化生成方法已经无法同时满足用户的需求&#xff0c;这次腾讯发布了PhotoMaker框架&#xff0c;可以在…

IaC基础设施即代码:Terraform 通过后端使用 alicloud的OSS 实现资源管理

目录 一、实验 1.环境 2.Windows创建Terraform后端项目 3.Windows实例化Terraform后端项目 3.Windows给Terraform项目添加alicloud阿里云OSS &#xff08;实现代码与资源分离&#xff09; 4.Windows给Terraform项目添加封装的模块 5.Terraform通过后端使用 alicloud阿里…

价值7500的在线授权网站源码支持IP+域名+双向授权全开源

PHP授权验证更新系统完整版&#xff0c;一键更新系统&#xff0c;一键卡密生成自助授权功能&#xff0c;域名ip双重验证功能等等 修复盗版检测&#xff0c;确保实时查看盗版 修复在线加密系统&#xff0c;一键加密 授权系统几乎所有的程序都能整合使用,包括您的app和计算机程序…

el-table右固定最后一列显示不全或者是倒数第二列无边框线

问题图片&#xff1a; 解决方式1&#xff1a; >>>.el-table__row td:not(.is-hidden):last-child { border-left:1px solid #EBEEF5; } >>>.el-table__header th:not(.is-hidden):last-child{ border-left:1px solid #EBEEF5; } >>>.el-table__head…

文件压缩完还是过大怎么办?这些参数你设置了吗?

不同的压缩算法对不同类型的文件可能有不同的效果。尝试使用不同的压缩算法、压缩模式、调整压缩工具的参数或者设置输出的文件格式等方法解决问题。下面以嗨格式压缩大师作为操作示范。 方法一&#xff1a;对文件进行分类压缩 将文件按照视频、图片、pdf、word、PPT分类压缩…

uni-app的项目创建和环境搭建

uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;开发者编写一套代码&#xff0c;可发布到iOS、Android、Web&#xff08;响应式&#xff09;、以及各种小程序&#xff08;微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝&#xff09;、快应用等多个平台。 第一步…