『C语言进阶』字符函数和内存函数(1)

news2024/11/18 5:53:01

在这里插入图片描述
🔥博客主页 小羊失眠啦.
🔖系列专栏 C语言LinuxCpolar
❤️感谢大家点赞👍收藏⭐评论✍️


在这里插入图片描述

前言

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符串中。

字符串常量适用于那些对它不做修改的字符串函数。

今天我们将学习有关库函数以及模拟实现,在此之前必须要了解这两个const关键字assert库函数

  1. const关键字

    const详解

  2. assert函数

    函数名:断言函数

    头文件:

    #include<assert.h>
    

    作用:

    判断参数表达式的真假,如果为假就会终止程序,打印错误信息。
    对于程序员这是一个非常友好的函数,可以减少出错的可能性,由于会返回错误到具体的哪一行,也就省去了调试的成本。
    assert()中的参数表达式为真时,什么也不会发生,在release版本中,assert会被优化掉。


一、strlen函数

1.1 函数认识

在这里插入图片描述

函数功能:

strlen函数的功能是用于计算字符串的长度(输入字符串首地址,返回字符串长度)

头文件

#include<string.h>

返回值

字符串’\0’之前的字符个数(不包括’\0’)

strlen函数的使用

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[]="abcdef";
    int len=strlen(arr);
	printf("字符串长度%d", len);
	return 0;
}

1.2 注意事项

  • 字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )
  • 参数指向的字符串必须要以 ‘\0’ ,如果字符串没有包含’\0’,就会接续往后寻找,直到遇到’\0’,即产生随机值
  • 函数的返回值为size_t,是无符号的(易错)
  • 库函数strlen的返回值是size_t,所以strlen不能用于加减:strlen(“abc”)-strlen(“abcdefg”)结果是一个size_t类型的数,不会是-4(可以用强制转换解决)

1.3 模拟实现

//模拟实现strlen
#include <stdio.h>
#include <assert.h>
size_t my_strlen1(const char* str)//方法一:计数法
{
	assert(str);
	int count = 0;
	while (*str++)
	{
		count++;
	}
	return count;
}
size_t my_strlen2(const char* str)//方法二:递归方式实现
{
	assert(str);
	if (*str != '\0')
	{
		return 1 + my_strlen2(str + 1);
	}
	return 0;
}
size_t my_strlen3(const char* str)//方法三:指针-指针
{
	assert(str);
	char* ret = str;
	while (*ret)
	{
		ret++;
	}
	return ret - str;
}
int main()
{
	char arr[] = { "abcdefg" };
	printf("%d\n", my_strlen1(arr));
	printf("%d\n", my_strlen2(arr));
	printf("%d\n", my_strlen3(arr));
	return 0;
}


二、strcpy函数

2.1 函数认识

在这里插入图片描述

函数功能

拷贝字符串:将源字符串拷贝到目标空间

头文件

#include<string.h>

返回值

拷贝完成后的目标空间地址

strcpy函数的使用

#include<stdio.h>
#include <string.h>
int main()
{
	char arr1[20] =  "xxxxxxxxxxxxxxx" ;
	char arr2[] = "hello csdn" ;
	printf("%s", strcpy(arr1, arr2));
	return 0;
}

2.2 注意事项

  • 源字符串必须以’\0’结束,没有’\0’拷贝无法停止
  • 目标空间必须足够大,以确保能存放源字符串(strlen是不管目标空间可不可以放进去)
  • 目标空间可以被修改
  • 拷贝字符串时,'\0’也会被拷贝
  • 可以用const修饰源字符串,使源字符串不能被修改

2.3 模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy1(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;
	return ret;
}

char* my_strcpy2(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[] = { "hello csdn!" };
	char arr2[20] = { "xxxxxxxxxxxxxxxxxx" };
	char* p = NULL;
	printf("%s\n", my_strcpy1(arr2, arr1));
	printf("%s\n", my_strcpy2(arr2, arr1));
	return 0;
}


三、strcat函数

3.1 函数认识

在这里插入图片描述

函数功能

将源字符串(source)的副本(复制一份)追加到目标字符串(destination)。目标中的终止空字符(‘\0’)被源字符串的第一个字符覆盖,并且在目标中由两者串联形成的新字符串的末尾包含一个空字符(‘\0’)。
在这里插入图片描述

头文件

#include<string.h>

strcat函数的使用

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "HELLO ";
	char arr2[] = "CSDN!";
	strcat(arr1,arr2);
	printf("%s", arr1);
	return 0;
}

3.2 注意事项

  • 源字符串必须以’\0’结束
  • 目标空间必须有足够的大,能容纳下源字符串的内容
  • 目标空间可以被修改
  • 目的地和来源不可重叠,简单来说就是不可自己追加自己,否则不知道什么时候停下来,因为’\0’被改掉了

3.3 模拟实现

#include <stdio.h>
#include <assert.h>
my_strcat(char* dest, const char* src)
{
	assert(dest && src);//防止传入空指针
	char* ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[20] = "HELLO ";
	char arr2[] = "CSDN!";
	my_strcat(arr1,arr2);
	printf("%s", arr1);
	return 0;
}

四、strcmp函数

4.1 函数认识

函数功能

将字符串 str1 与 字符串 str2 进行比较。
此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续向后比较,直到字符不同或达到终止空字符。

头文件

#include<string.h>

返回值

返回值意义
<0第一个不匹配的字符的str1的值小于str2中的值
0两个字符串的内容相等
>0第一个不匹配的字符的str1的值大于str2中的值

strcmp函数的应用

#define MAX 3
#include <stdio.h>
#include <string.h>
int main()
{
	char password[] = "092755";
	char input[20];
	for (int i = 1; i <= MAX; i++)
	{
		printf("请输入密码:>", i);
		scanf("%s", input);
		if (strcmp(password, input) == 0)
		{
			printf("恭喜你,密码正确!!!");
			break;
		}
		else
		{
			printf("很遗憾,密码错误\n");
			if (i == MAX)
				printf("你没有机会了");
			else
			    printf("你还有%d次机会\n", MAX - i);
		}
	}
	return 0;
}

4.2 注意事项

此函数执行字符的二进制比较,实际比较的是字符的ASCII码值,并不是按长度比较,而是比较第一次出现不同字符的大小
在vs编译器下,

第一个字符串大于第二个字符串,返回1;
第一个字符串相等第二个字符串,返回0;
第一个字符串小于第二个字符串,返回-1;
而与库函数本身有点小的差别,库函数要求返回>0 0和<0的数即可

4.3 模拟实现

#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 arr1[] = "abcde";
	char arr2[] = "abc";
	int ret = my_strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

五、strncpy函数

5.1 函数认识

strncpy函数相较于strcpy函数多了一个参数size_t num

函数功能:

拷贝num个字符从源字符串到目标空间

头文件:

#include<string.h>

strncpy函数的应用:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "xxxxxxxx";
    strncpy(arr1, arr2, 3)printf("%s\n",arr1 );
	return 0;
}

5.2 注意事项

如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后面追加’\0’,直到num个

5.3 模拟实现

#include <stdio.h>
#include <string.h>
#include <assert.h> 
 
char* my_strncpy(char* dest, const char* src, int num)
{
	assert(dest && src);
	char* s = dest;
	int i = 0;
	for (i = 0; i < num; i++)
	{
		*dest++ = *src++;
	}
	return s;
}
 
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "xxxxxxxx";
	printf("%s\n", my_strncpy(arr1, arr2, 3));
	return 0;
}

六、strncat函数

6.1 函数认识

函数功能:

将源字符串的num个字符连接到目标字符串后面

头文件:

#include<string.h>

strncat函数的应用:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello";
	char arr2[] = "wordasdd";
	strncat(arr1, arr2, 4);
	printf("%s\n", arr1);
	return 0;
}

6.2 注意事项

如果源字符串的长度大于num,则追加num个源字符串之后,再在后面加一个’\0’

如果源字符串的长度小于num,则追加完源字符串之后,再在后面加一个’\0’就可以了

6.3 模拟实现

#include <stdio.h>
#include <string.h>
#include <assert.h> 
 
char* my_strncat(char* dest, const char* src, int num)
{
	assert(dest && src);
	char* s = dest;
	while (*dest)
	{
		dest++;
	}
	while (num--)
	{
		*dest++ = *src++;
	}
	return s;
}
 
int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "wordasdaf";
	printf("%s\n", my_strncat(arr1, arr2, 4));
	return 0;
}

七、strncmp函数

7.1 函数认识

函数认识:

比较前num个字符的大小

头文件:

#include<string.h>

返回值:

返回值表明
<0不匹配的第一个字符在str1中的值低于str2中的值
0两个字符串的内容相等
>0第一个匹配的字符在str1中的值大于str2中的值

strncmp函数的应用:

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcde";
	char arr2[] = "abc";
	int ret = strncmp(arr1, arr2, 3);
	printf("%d\n", ret);
	return 0;
}

7.2 模拟实现

#include <stdio.h>
#include <string.h>
#include <assert.h> 
 
int my_strncmp(const char* dest, const char* src, int num) 
{
	int ret = 0;
	assert(dest != NULL);
	assert(src != NULL);
	while (!(ret = *(unsigned char*)src - *(unsigned char*)dest) && *dest) 
    {
		++dest;
		++src;
	}
	if (ret < 0) 
    {
		ret = 1;
	}
	else if (ret > 0) 
    {
		ret = -1;
	}
	return ret;
}
 
int main() 
{
	char arr1[20] = "abcde";
	char arr2[]= "abcdf";
	printf("%d\n", my_strncmp(arr1, arr2, 4));
	return 0;
}

八、strstr函数

8.1 函数认识

在这里插入图片描述

函数功能:

在str1中找str2第一次出现的位置

返回值:

指向str1中指定的整个字符序列在str2中首次出现的指针,如果序列在str1中不存在,则为null指针。

头文件:

#include<string.h>

strstr函数的应用:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "abcdsfr";
	char arr2[] = "cdse";
	char* ret = strstr(arr1, arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到\n");
	return 0;
}

8.2 模拟实现

#include <stdio.h>
#include <string.h>
#include <assert.h> 
 
char* my_strstr(const char* str1, const char* str2)
{
    assret(str1&&str2);
    if(*str2 == '\0')
    {
        return (char*)str1;
    }
	char* cp = str1;
	char* s1 = cp;
	char* s2 = str2;
	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return (char*)cp;
		cp++;
	}
    return NULL;
}
 
int main() 
{
	char arr1[] = "abcdsfr";
	char arr2[] = "cdse";
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到\n");
	return 0;
}

本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位铁汁们的支持。文章有任何问题可以在评论区留言,小羊一定认真修改,写出更好的文章~~

在这里插入图片描述

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

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

相关文章

【python】机器学习-K-近邻(KNN)算法

目录 一 . K-近邻算法&#xff08;KNN&#xff09;概述 二、KNN算法实现 三、 MATLAB实现 四、 实战 一 . K-近邻算法&#xff08;KNN&#xff09;概述 K-近邻算法&#xff08;KNN&#xff09;是一种基本的分类算法&#xff0c;它通过计算数据点之间的距离来进行分类。在…

【CSS】全局滚动条样式设置

直接在 App.vue 全局文件下设置滚动条样式&#xff1a; ::-webkit-scrollbar {width: 5px;position: absolute; } ::-webkit-scrollbar-thumb {background: #1890ff; } ::-webkit-scrollbar-track {background: #ddd; }

力扣每日一题51:N皇后问题

题目描述&#xff1a; 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问…

【51单片机外部中断控制流水灯转向】2023-10-21

缘由单片机不会搞 原理都清晰合一块成傻杯了 各位爷 用keil Vison5 还有Proteus8仿真图给出一下吧_嵌入式-CSDN问答 #include <reg52.h> unsigned char Js0; bit k0; void main() {//缘由unsigned char ls0; EA1;//总中断允许EX01;//允许外部中断0中断TH0(65536-50000)…

mysql优化之explain详解

mysql的explain&#xff08;执行计划&#xff09;用于解释sql的执行的过程&#xff0c;然后把sql的执行过程用一张表格表示出来&#xff0c;它并不真正的执行sql&#xff0c;如下图。explain能够为我们优化sql提供很好参考作用。 下面我来看下执行计划表中各个字段是什么意思 i…

【Linux】kill 命令使用

经常用kill -9 XXX 。一直在kill&#xff0c;除了kill -9 -15 &#xff0c;还能做什么&#xff1f;今天咱们一起学习一下。 kill 命令用于删除执行中的程序或工作。 kill命令 -Linux手册页 命令选项及作用 执行令 man kill 执行命令结果 参数 -l 信号&#xff0c;若果…

【吞噬星空】又被骂,罗峰杀人目无法纪,但官方留后手,增加审判戏份

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫吞噬星空资讯。 吞噬星空动画中&#xff0c;罗峰复仇的戏份&#xff0c;简直是帅翻了&#xff0c;尤其是秒杀阿特金三大巨头&#xff0c;让人看的也是相当的解气&#xff0c;相当的爽&#xff0c;一点都不拖沓&#x…

有什么站内搜索引擎优化的方法?今天跟大家分享!

在你的网站上安装站内搜索引擎对于提升用户体验和增加互动至关重要。在今天快节奏的数字世界中&#xff0c;用户希望能够快速、轻松地找到信息。通过提供站内搜索引擎&#xff0c;用户能够轻松浏览你的网站&#xff0c;帮助他们找到他们正在寻找的具体信息。接下来我将跟大家介…

浅析高校用电问题及智慧电力监管平台的构建

安科瑞 崔丽洁 摘 要&#xff1a;介绍了当前高校用电存在的问题&#xff0c;进行了原因分析&#xff0c;由此提出建立高校用电智慧监管平台。对高校用电智慧监管平台的构架进行设计&#xff0c;运用物联网技术&#xff0c;实现各回路实时自主控制&#xff0c;并细化管理权限&a…

ATA-8202射频功率放大器在超声雾化研究中的应用

超声雾化技术是一种利用高频声波能量产生微细液滴的技术&#xff0c;广泛应用于医学、生物科学、材料科学等领域。在超声雾化过程中&#xff0c;功率放大器扮演着关键的角色&#xff0c;它能提供足够的能量来驱动超声发射装置&#xff0c;并调节声波参数&#xff0c;实现有效的…

【数据结构】线性表(八)队列:顺序队列及其基本操作(初始化、判空、判满、入队、出队、存取队首元素)

文章目录 一、队列1. 定义2. 基本操作 二、顺序队列0. 顺序表1. 头文件和常量2. 队列结构体3. 队列的初始化4. 判断队列是否为空5. 判断队列是否已满6. 入队7. 出队8. 存取队首元素9. 主函数10. 代码整合 堆栈Stack 和 队列Queue是两种非常重要的数据结构&#xff0c;两者都是特…

论文浅尝 | Concept2Box:从双视图学习知识图谱的联合几何嵌入模型

笔记整理&#xff1a;张钊源&#xff0c;天津大学硕士&#xff0c;研究方向为知识图谱 链接&#xff1a;https://virtual2023.aclweb.org/paper_P4210.html 动机 知识图嵌入&#xff08;KGE&#xff09;已被广泛研究&#xff0c;用于嵌入大规模关系数据以满足许多现实世界的应用…

Spring Security总体架构介绍

参考&#xff1a;架构 :: Spring Security Reference (springdoc.cn) 一、过滤器 Spring Security 框架对 Servlet 请求的处理是基于过滤器机制。 容器会提前创建好FilterChain对每一个请求进行过滤&#xff0c;FilterChain中包含Filter 实例和 Servlet&#xff08;Spring MV…

编写后台登录滑动成功获取验证码 人机验证

vue-puzzle-vcode Vue 纯前端的拼图人机验证、右滑拼图验证 安装vue-puzzle-vcode npm install vue-puzzle-vcode --save使用vue-puzzle-vcode import Vcode from "vue-puzzle-vcode";<Vcode :show"isShow" success"onSuccess" close"…

ZooKeeper+HBase分布式集群环境搭建

安装版本&#xff1a;hadoop-2.10.1、zookeeper-3.4.12、hbase-2.3.1 一、zookeeper集群搭建与配置 1.下载zookeeper安装包 2.解压移动zookeeper 3.修改配置文件&#xff08;创建文件夹&#xff09; 4.进入conf/ 5.修改zoo.cfg文件 6.进入/usr/local/zookeeper-3.4.12/zkdat…

虚拟机与主机(win10之间的通信)

(201条消息) Ubuntu虚拟机不显示ip地址【已解决】_ubuntu没有ip_不爱赖床的懒虫的博客-CSDN博客 sudo /sbin/dhclient VMTool安装与卸载 (201条消息) ubuntu中vmtools的安装与彻底卸载_卸载vmtools_林麦安的博客-CSDN博客 (202条消息) 解决虚拟机安装 VMware Tools 灰色无法…

聊聊RocketMQ中的broker的TPS和QPS为何相差巨大,是如何统计的

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 最近在看RocketMQ的一些监控指标的时候&#xff0c;总觉得一些监控指标不太对&#xff0c;好像对不上。 所以打算研究下看看RocketMQ中的 broker TPS、broker QP…

嵌入式学习笔记(60)内存管理之堆

1.7.1.什么是堆&#xff08;heap&#xff09; 内存管理对OS来说是一件非常复杂的事&#xff0c;因为首先内存容量大&#xff0c;其次内存需求在时间和大小块上没有规律&#xff08;OS上运行着几十、几百、几千个进程随时都会申请或者释放内存&#xff0c;申请或者释放的内存块…

JavaWeb从入门到起飞笔记——导学课程

学完这一节&#xff0c;我不知道学Web开发究竟能干什么&#xff1f;你知道吗&#xff1f; 以下是黑马程序员Java从入门到起飞的笔记 一、学完Javaweb能干什么&#xff1f; 学完Java后我们可以独立开发一些后台管理系统&#xff0c;例如CRMER器&#xff0c;京东和淘宝&#x…

tuxera ntfs2024破解版mac电脑磁盘读写软件

大家都知道由于操作系统的原因&#xff0c;在苹果电脑上不能够读写NTFS磁盘&#xff0c;但是&#xff0c;今天小编带来的这款tuxera ntfs 2024 mac版&#xff0c;完美的解决了这个问题。这是一款在macOS平台上使用的磁盘读写软件&#xff0c;能够实现苹果Mac OS X系统读写Micro…