一篇文章让你看懂C语言字符函数和内存函数

news2024/11/25 12:25:34

目录

一、字符函数

1.strlen函数

 1.1strlen函数的介绍

1.2strle函数的使用

1.3模拟实现strlen 

1.3.1指针移动法

1.3.2指针减去指针法 

 1.3.3函数递归法

 2.strcpy函数

​编辑

  2.1strcpy函数的介绍

2.2strcpy函数的使用

 2.3模拟实现strcpy

 3.strcat函数

 3.1strcat函数的介绍

3.2strcat函数的使用

 3.3模拟实现strcat

4.strcmp函数

4.1strcmp函数的介绍 

4.2strcmp函数的使用

4.3模拟实现strcmp函数

5.strstr函数

 5.1strstr函数的介绍

5.2strstr函数使用

 5.3模拟实现strstr函数

 二、内存函数

1.memcpy函数

 1.1memcpy函数的介绍

1.2 memcpy函数的使用

 1.3模拟实现memcpy

 2.memmove函数​编辑

2.1memmove函数的介绍

2.2memmove函数的使用

2.3模拟实现memmove


一、字符函数

1.strlen函数

 1.1strlen函数的介绍

strlen函数的作用:得到一个 字符串的长度

通过查询我们看到strlen函数的定义:参数为const修饰的指针,返回类型为size_t。

注意:

1. strlen函数的返回类型为size_t(无符号整形)

int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)
	{
		printf("大于\n");
	}
	else
	{
		printf("小于等于\n");
	}
	return 0;
}

 

 为什么是大于呢?

-3 
原码:1000 0000 0000 0000 0000 0000 0000 0011
反码:1111 1111 1111 1111 1111 1111 1111 1100
补码:1111 1111 1111 1111 1111 1111 1111 1101
因为是无符号数最高位就不是符号为是一个大于零数所以打印结果为大于

2.所求字符串必须是以'\0'结尾

int main()
{
	char arr[5] = { 'a','b','c','d','e' };
	printf("%d \n", strlen(arr));
	return 0;
}

 

1.2strle函数的使用

int main()
{
	char arr[] = "hello world";
	printf("%d\n", strlen(arr));
	return 0;
}

1.3模拟实现strlen 

这里提供三种方法给大家参考

1.3.1指针移动法

size_t my_strlen(char* str) 
{
	int num = 0;
	while (*str != 0)
	{
		str++;
		num++;
	}
	return num;
}
int main()
{
	size_t ret = my_strlen("abcdef");
	printf("%d\n", ret);
	return 0;
}

1.3.2指针减去指针法 

size_t my_strlen(char* str)
{
	char* p = str;
	while (*str != '\0')
	{
		str++;
	}
	return str - p;
}
int main()
{
	size_t ret = my_strlen("abcdef");
	printf("%d\n", ret);
	return 0;
}

 1.3.3函数递归法

size_t my_strlen(char* str)
{
	if (*str == 0)
	{
		return 0;
	}
	else
	{
		str++;
		return 1 + my_strlen(str);
	}
}
int main()
{
	size_t ret = my_strlen("abcdef");
	printf("%d \n", ret);
	return 0;
}

 2.strcpy函数

  2.1strcpy函数的介绍

strcpy函数的作用:将一个字符串拷贝到另外一个字符串中

通过查询我们可知:strcpy函数的返回类型为char *,第一个参数为 char *destination (目标字符串指针),第二个参数为 char * source(被拷贝字符串的指针)

注意:

1.源字符串必须以 '\0' 结尾。

2.会将源字符串中的'\0'拷贝到目标空间。

3.目标空间必须走勾搭,以确保能存放源字符串

4.目标空间必须可变。

2.2strcpy函数的使用

int main()
{
	char arr1[] = "xxxxxxxxxxxxxxx";
	printf("arr1拷贝前:%s \n",arr1);
	char arr2[10] = "abcdefgh";

	char* ret = strcpy(arr1, arr2);
	printf("\narr1拷贝后: %s \n", ret);
	return 0;
}

 2.3模拟实现strcpy

char* my_strcpy(char* str2,const char* str1)
{
	assert(*str1 && *str2);
	char* ret = str2;
	while (*str1) 
	{
		*str2 = *str1;
		str1++;
		str2++;
	}
	*str2 = *str1;  
    //源字符串 '\0'的打印

	while (*str2++ = *str1++)
	{
		;
	}
	return ret;
}


int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "xxxxxxxxxx";
    //目标空间必须可变
	printf("arr2数组copy前:%s\n", arr2);
	char *p=my_strcpy(arr2, arr1);
	printf("arr2数组copy后:%s\n",p);
	return 0;
}

 3.strcat函数

 3.1strcat函数的介绍

strcat函数的作用:用于将一个字符串(源字符串)连接到另一个字符串(目标字符串)的末尾,简单点来说就是将两个毫不相干的字符串连接在一起组成一个新的字符串。

通过查询我们可知:strcat函数的参数,返回值类型和strcpy函数的类型和意义都相同

注意:

1.源字符串必须以 '\0' 结尾

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

3.目标空间必须可以修改。

3.2strcat函数的使用

int main()
{
	char arr1[100] = "hello ";
	char arr2[10] = "world";
	char* ret = strcat(arr1, arr2);
	printf("%s \n", ret);
	return 0;
}

 3.3模拟实现strcat

char* my_strcat(char* str1,const char* str2)
{
	char* p = str1;
	while (*str1 != '\0')
	{
		str1++;
	}
	while (*str1++ = *str2++);
	return p;
}
int main()
{
	char arr1[100] = "hello ";
	char arr2[] = "world";
	char* ret = my_strcat(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

4.strcmp函数

4.1strcmp函数的介绍 

strcmp函数的作用:用于比较两个字符串的大小。

通过查询我们可知:strcmp函数的返回值为intl类型,参数为const修饰不可修改的连个 char * 类型的指针;

注意:

标准规定:

第一个字符串大与第二个字符串,则返回大于0的数字。

第一个字符串等于第一个字符串,则返回0。

第一个字符串小于第一个字符串,则返回小于0的数字。

那么如何判断两个字符串呢?

说是比较字符串的大小,其实是比较字符传中每个字符的大小。

从两个字符串中的起始字符开始按照标准规定一个一个比较下去,知道判断出某一个字符的大小,才会返回数字,如果返回0的话意味着两个字符串中的每个字符都相等。

4.2strcmp函数的使用

int main()
{
	char arr1[] = "abc";
	char arr2[] = "adc";
	int ret = strcmp(arr1, arr2);
	printf("%d \n", ret);
	return 0;
}

 在这个例子中arr1字符串中的第二个字符 'b' 小于arr2字符串中的第二个字符 'd',所以返回一个小于0的数字。

4.3模拟实现strcmp函数

int my_strcmp(char* str1, char* str2)
{
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main()
{
	char arr1[] = "abc";
	char arr2[] = "abc";
	int ret = my_strcmp(arr1,arr2);
	printf("%d\n", ret);
	return 0;
}

5.strstr函数

 5.1strstr函数的介绍

strstr函数的作用:用于在一个字符串中查找另一个字符串的第一次出现的位置。(判断一个字符串是否为一个字符串的子字符串)。

通过查询我们可知:strstr函数的返回值为char * 类型的指针,参数为两个不可修改的char *类型的指针

5.2strstr函数使用

int main()

{

	char arr1[] = "abbbcde";
	char arr2[] = "bbc";

	char* ret = strstr(arr1, arr2);
	printf("%s \n", ret);
	return 0;
}

 5.3模拟实现strstr函数

char* my_strstr(char *str1, char* str2)
{
	char* cp = str1;
	char* s1 = str1;
	char* s2 = str2;
	if (*str2 == '\0')
		return str1;
	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return cp;
		cp++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";

	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到\n");
	return 0;
}

 二、内存函数

1.memcpy函数

 1.1memcpy函数的介绍

通过查询我们可知:用于将一段内存的内容复制到另一段内存区域。

1. 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
2. 这个函数在遇到 '\0' 的时候并不会停下来。
3. 如果source和destination有任何的重叠,复制的结果都是未定义的

1.2 memcpy函数的使用

将arr1中的40个字节的数据复制到arr2中

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
	int arr2[20] = { 0 };
	memcpy(arr2, arr1, 40);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

 1.3模拟实现memcpy

void* my_memcpy(void* dest, void* src, size_t num)
{
	void* ret = dest;
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}

	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	my_memcpy(arr2, arr1, 40);

	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

 2.memmove函数

2.1memmove函数的介绍

通过查询我们可知:用于在内存中移动一段数据块的内容。

1. 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
2. 如果源空间和目标空间出现重叠,就得使用memmove函数处理。 

2.2memmove函数的使用

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
	memmove(arr1 + 2, arr1, 20);

	int i = 0;

	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

2.3模拟实现memmove

void* my_memmove(void* dest, void* src,size_t num)
{
	void* ret = dest;
	if (dest < src)
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1, arr1+2 ,20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

 

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

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

相关文章

LiveGBS流媒体平台GB/T28181功能-支持海康大华GB28181语音对讲需要的设备及服务准备

LiveGBS支持海康大华GB28181语音对讲需要的设备及服务准备 1、背景2、准备2.1、服务端必备条件&#xff08;注意&#xff09;2.2、准备语音对讲设备2.2.1、 大华摄像机2.2.1.1、 配置接入示例2.2.1.2、 配置音频通道编号 2.2.2、 海康摄像机2.2.2.1、 配置接入示例 3、开启音频…

初试Python路径库

文章目录 一、pathlib概述二、操作路径对象(一)操作属性(二)连接路径(三)拆分完整路径三、路径对象的常用函数(一)获取当前工作目录(二)创建新目录(三)查看主目录一、pathlib概述 自Python 3.4 以来,pathlib一直是标准库的一部分。 PurePath, PurePosixPath, Pure…

即视角|出海资本热土——印尼市场洞察(上)

即视角Insight 共享即构新洞察&#xff0c;共建行业新动能——ZEGO即构科技基于音视频技术领域的多年深耕&#xff0c;综合面向各行业的服务经验&#xff0c;在【即视角】栏目发布即构对行业的洞察。 此前我们根据即构对出海客户的服务经验&#xff0c;输出了文章《即视角&am…

STL标准模板库 set容器

文章目录 迭代器迭代器的五大分类迭代器系列帮手函数一览 set容器打印任意 STL 容器的printer.hset与vectorset 和 vector 的区别set 和 vector 迭代器的共同点set 和 vector 迭代器的不同点 set 的排序set 的排序&#xff1a;string 会按“字典序”来排set 的排序&#xff1a;…

ai智能绘画生成器有哪些?你知道ai生成图片网站哪个好吗?

曾经有一个年轻的画家&#xff0c;名叫亚历克斯。他对艺术充满了热情和渴望&#xff0c;但却常常感到自己的创作灵感有限。每当他拿起画笔&#xff0c;总是困扰于如何将心中的景象完美地呈现在画布上。 有一天&#xff0c;亚历克斯偶然听说了一个神奇的网站&#xff0c;据说这…

【力扣】20. 有效的括号

有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相…

uniapp H5预览PDF文件

1&#xff0c;下载资源后hybrid文件存放在static静态文件里 (点击这里去下载文件) 2&#xff0c;pdf预览页面配置 <template><view style"width: 100vh;"><web-view :src"pdfUrl"></web-view></view> </template><…

【每日一题】1289. 下降路径最小和 II

【每日一题】1289. 下降路径最小和 II 1289. 下降路径最小和 II题目描述解题思路 1289. 下降路径最小和 II 题目描述 给你一个 n x n 整数矩阵 grid &#xff0c;请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下降路径 定义为&#xff1a;从 grid 数组中的每一行选择…

【计算机视觉】简述对EQ-Net的理解

最近又看了一些点云分割的文章&#xff0c;近两年点云分割的文章是真的少&#xff0c;不知道是不是点云分割算法接近了末端。这篇文章主要提出了一个基于查询方法的统一范式&#xff0c;它解决了一些不仅仅是点云分割的问题&#xff0c;还解决了三维点云分类和三维目标检测的问…

解密AI图像安全技术:智能守护数智时代,低代码平台助力圈复杂操作!

前言 随着数智时代的来临&#xff0c;人们进入了一个全新的智能化世界。在这个时代中&#xff0c;人工智能&#xff08;AI&#xff09;成为了一项重要的技术突破&#xff0c;其应用也无处不在。其中&#xff0c;AI图像安全技术作为保障个人和企业数据安全的重要环节&#xff0c…

Linux——认识Linux的目录结构 常用命令 vim命令 权限及其控制

目录 linux的目录结构常用linux的命令ls(list)和llcd 切换目录mkdir 创建文件夹touch命令&#xff1a;创建普通文本文件pwd 显示路径whoamisu&#xff1a;普通--超级账号man&#xff1a;查看手册rm&#xff1a;删除网络命令ifconfig重定向 >>cat 查看文本文件clear清屏hi…

3.2 Bootstrap 下拉菜单(Dropdowns)

文章目录 Bootstrap 下拉菜单&#xff08;Dropdowns&#xff09;选项对齐标题 更多实例 Bootstrap 下拉菜单&#xff08;Dropdowns&#xff09; 本章将重点介绍 Bootstrap 下拉菜单。下拉菜单是可切换的&#xff0c;是以列表格式显示链接的上下文菜单。这可以通过与 下拉菜单&a…

NZ12:VBA给批量文件重命名

【分享成果&#xff0c;随喜正能量】沉默&#xff0c;可以让混乱的心&#xff0c;变得清澈。沉默&#xff0c;是城府&#xff0c;是睿智&#xff0c;是内涵&#xff1b;沉默&#xff0c;是最后的清高&#xff0c;也是最后的自由。。 我的教程一共九套及VBA汉英手册一部&#x…

nginx添加模块fastdfs-nginx-module(docker版,不需要重写dockerfile)

nginx添加模块fastdfs-nginx-module&#xff08;docker版&#xff0c;不需要重写dockerfile&#xff09; 一、fastdfs-nginx-module模块准备1.1、下载模块1.2、配置模块参数 二、重新制作nginx的二进制执行文件2.1、查看nginx版本2.2、下载nginx配套版本的源码文件2.3、制作ngi…

线性表综合应用题2

设计一个高效算法&#xff0c;将顺序表L的所有元素逆置&#xff0c;要求算法的空间复杂度为O(1)。 算法思想&#xff1a;扫描顺序表L的前半部分元素&#xff0c;对于元素L.data[i] (0<i<L.length/2),将其与后半部分的对应元素L.data[L.length - i - 1]进行交换。 #defi…

GC overhead limit exceeded问题

GC overhead limit exceeded问题 一、为什么会产生GC overhead limit exceeded问题 OutOfMemoryError是java.lang.VirtualMachineError的子类&#xff1b;JVM遇到与资源利用有关的问题时&#xff0c;会抛出该错误。更具体地说&#xff0c;当JVM花太多时间执行垃圾回收并且只能…

807. 区间求和

链接&#xff1a; 链接 题目&#xff1a; 输入两个整数 ll 和 rr&#xff0c;请你编写一个函数&#xff0c;int sum(int l, int r)&#xff0c;计算并输出区间 [l,r][l,r] 内所有整数的和。 输入格式 共一行&#xff0c;包含两个整数 ll 和 rr。 输出格式 共一行&#xff0c;包…

分支IPSECV批恩连接总部突然上线不了,连接其他总部正常

环境: 分支: AF8.0.17 总部设备: SSL V批恩 V7.0 AF8.0.75 问题描述: 分支IPSECV批恩连接总部突然上线不了,之前正常,连接其他总部正常 解决方案: 排查&解决 1.先在分支和总部设备各查询故障日志 分支 总部 然后在分支AF上进入系统排障页面,测试ping总…

14、Horizontal Pod Autoscale

一、为何进行缩扩容&#xff1f; 在实际生产中&#xff0c;经常会遇到某个服务需要扩容的场景&#xff0c;可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景。可以利用Deployment/RC的Scale机制来完成这些工作。 二、缩扩容模式 Kubernetes 对 Pod 扩容与缩…

【Android Framework系列】第6章 AMS原理之Launcer启动流程

1 前言 我们在上一章节【Android Framework系列】第5章 AMS启动流程中简单的分析了AMS的启动流程&#xff0c;这一章节我们来了解一下&#xff0c;通过AMS是怎么完成Activity的启动 下面我们通过Launcher启动一起来看看Activity的启动流程 本文基于Android10&#xff08;Q&a…