【进阶C语言】字符串函数+内存函数

news2024/12/24 8:57:11

文章目录

  • 一.字符串函数
    • 1.strlen
      • 功能:求字符串长度(不包括\0)
      • 函数
      • 模拟实现:
    • 2.1 strcmp
      • 功能
      • 函数
      • 模拟实现
    • 2.2 strncmp
    • 3.1 strcat
      • 功能
      • 函数
      • 模拟实现
    • 3.2strncat
    • 4.1 strcpy
      • 功能
      • 函数
      • 模拟实现
    • 4.2 strncpy
    • 5.strstr
      • 功能
      • 函数
      • 模拟实现
    • 6.strtok
      • 功能
      • 函数
    • 7.strerror
      • 功能
      • 函数
  • 二.内存函数
    • 1.memcpy
      • 功能
      • 函数
      • 模拟实现
      • 2.memmove
    • 1.memcpy
      • 功能
      • 函数
      • 模拟实现

一.字符串函数

1.strlen

功能:求字符串长度(不包括\0)

函数

1.返回类型:无符号的int——size_t
2.函数参数:字符串的首地址(所求的在函数内部,不能发生改变,最好为const,也防止有人迷糊的时候写代码,把代码写的一团糟)

模拟实现:

#include <stdio.h>
#include <assert.h>
size_t  my_strlen(const char*str)
{
	assert(str);
	char* ret = str;
	while (*str++)
	{
		;
	}
	return (str - ret -1);
}
int main()
{
	char str[] = "Geneius";
	printf("%d",my_strlen(str));
	return 0;
}

2.1 strcmp

功能

字符串比较

函数

1.返回类型:有符号的int。

如果相等则返回0。
如果所正在比较的字符相减大于0,返回一个大于0的数。
如果所正在比较的字符相减小于0,返回一个小于0的数。

2.参数

1.要比较的字符串1
2.要比较的字符串2

注意:这里的相减指的是——所正在比较的字符串1的字符减去字符串2的字符。

模拟实现

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while ((*str1 == *str2)&&*str1&&*str2)
	{
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main()
{
	char str[] = "Geneius";
	char str1[] = "Geneis";
	printf("%d", my_strcmp(str, str1));
	return 0;
}

2.2 strncmp

1.这的参数比strcmp多了一个:size_t num(要比较的字节)
2.比strcmp更加安全,因为这比较的字节数是自己设定的,会多想一下。

3.1 strcat

功能

字符串追加

函数

1.返回类型:char *
2.参数:

1.目标字符串的首字母的地址
2.追加的字符串的首字母的地址
注意:
1.源字符串必须以 ‘\0’ 结束。
2.目标空间必须有足够的大,能容纳下源字符串的内容。
3.目标空间必须可修改。
4.字符串不能自己给自己追加

模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
	char* ret = src;
	assert(src && dest);
	while (*src != 0)
	{
		src++;
	}
	while (*dest++=*src++)
	{
		;
	}
	return ret;
}
int main()
{
	char str[20] = "Geneius";
	char str1[] = "Geneius";
	printf("%s", my_strcat(str, str1));
	return 0;
}

3.2strncat

1.这的参数比strcat多了一个:size_t num(要追加的字节)
2.比strcat更加安全,因为这追加的字节数是自己设定的,会多想一下。
3.如果大于字符串本身的字节数,则与strcat相同。到\0停止,不追加\0.

4.1 strcpy

功能

字符串拷贝

函数

1.返回类型:char *
2.参数:

1.源字符串的地址
2.目标字符串的地址
注意:
1.源字符串必须以 ‘\0’ 结束。
2.会将源字符串中的 ‘\0’ 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串。
4.目标空间必须可变

模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char*dest,const char*src)
{ 
	assert(src && dest);
	char* ret = dest;
	while (*dest++=*src++)
	{
		;
	}
	return ret;
}
int main()
{
	char str[20] = "Geneius";
	char str1[20] = { 0 };
	printf("%s", my_strcpy(str1,str));
	return 0;
}

4.2 strncpy

1.这的参数比strcpy多了一个:size_t num(要拷贝的字节)
2.如果多余本身则进行补\0

5.strstr

功能

在字符串1中,查找与字符串2具有相同的字符串。

函数

1.返回类型:char*
2.参数

1.字符串1的首字母的地址
2.字符串2的首字母的地址

模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* tmp = str1;
	char* tmp1 = str2;
	while (*str2 && *str1)
	{
		//if (*str2++ == *str1++)
		//{
		//	; 
		//}
		//else
		//{
		//	tmp++;
		//	str1 = tmp;
		//	str2 = tmp1;
		//}
		(*str2++ == *str1++) ? 0 : (tmp++, str1 = tmp, str2 = tmp1);
	}
	//if (*str2 == 0)
	//{
	//	return tmp1;
	//}
	//else
	//{
	//	return NULL;
	//}
	return (*str2 == 0) ? tmp1 : NULL;
}
int main()
{
	char str[20] = "Geneius";
	char* p = "ne";
    printf("%s",my_strstr(str, p));
	return 0;
}

6.strtok

功能

在字符串1中分割出所需的字符串

函数

1.返回类型:char*
2.参数

1.字符串1的首字母的地址
2.字符串2(分割符可以是多个)的首字母的地址

注意:

1.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
2.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
2.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
3.如果字符串中不存在更多的标记,则返回 NULL 指针。

#include <stdio.h>
#include <string.h>
int main()
{
	
	char arr[20] = { 0 };
	char arr1[20] = { "abc.def@ghi" };
	strcpy(arr, arr1);
	printf("%s\n", arr1);
	char* p = ".@";
	char* ret = NULL;
	for (ret = strtok(arr, p); ret != NULL; ret = strtok(NULL, p))
	{
		printf("%s\n", ret);
	}
	return 0;
}

图解:
在这里插入图片描述

7.strerror

功能

返回错误码对应的错误信息(字符串)

函数

1.返回类型:char*
2.参数:int

#include <stdio.h>
#include <string.h>
int main()
{
	printf("1.%s\n\n", strerror(0));
	printf("2.%s\n\n", strerror(1));
	printf("3.%s\n\n", strerror(2));
	printf("4.%s\n\n", strerror(3));
	printf("5.%s\n\n", strerror(4));
	printf("6.%s\n\n", strerror(5));
	printf("7.%s\n\n", strerror(6));
	printf("8.%s\n\n", strerror(7));
	printf("9.%s\n\n", strerror(8));
	printf("10.%s\n\n", strerror(9));
	return 0;
}

图解:
在这里插入图片描述

二.内存函数

1.memcpy

功能

实现以字节为单位的拷贝(拷贝不重叠的内存)

函数

1.返回类型:void*
2.参数:

1.要拷贝的位置的地址(源头)——const void*
2.被拷贝的目标地址(目标)——void*
3.要拷贝的字节数——size_t
注意:size_t,需要包含头文件(stdio.h)才能使用

模拟实现

#include <stdio.h>
#include <assert.h>
void* my_mecpy(void *dest,const void *sour, size_t num)
{
	assert(dest && sour);
	while (num--)
	{
		*(char*)dest = *(char*)sour;
		++((char*)dest);
		++((char*)sour);
	}
}*
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	int sz = sizeof(arr1);
	my_mecpy(arr2, arr1, sz);
	return 0;
}

2.memmove

1.memcpy

功能

实现以字节为单位的拷贝(拷贝重叠的内存)

函数

1.返回类型:void*
2.参数:

1.要拷贝的位置的地址(源头)——const void*
2.被拷贝的目标地址(目标)——void*
3.要拷贝的字节数——size_t
注意:size_t,需要包含头文件(stdio.h)才能使用
在这里插入图片描述

模拟实现

void my_memove(void* dest, const void* sour, size_t num)
{
	assert(dest && sour);
	if (dest>sour)
	{
		//找到拷贝的最后一个字节的地址
		sour = (char*)sour + num -1;
		dest = (char*)dest + num -1;
		while (num--)
		{
			*(char*)dest = *(char*)sour;
			--((char*)dest);
			--((char*)sour);
		}
	}
	else
	{
		while (num--)
		{
			*(char*)dest = *(char*)sour;
			++((char*)dest);
			++((char*)sour);
		}
	}
}

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

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

相关文章

论文《An Effective Consistency Constraint for Sequential Recommendation》

C2Rec: An Effective Consistency Constraint for SequentialRecommendation 这篇文章提出了序列推荐建模中一种有效的一致性约束防范&#xff0c;不用修改模型结构&#xff0c;仅仅添加2个额外的损失函数&#xff0c;就能达到非常好的效果。不像基于对比学习的方法&#xff0…

C++初阶--string

目录 string对象的创建&#xff1a; 遍历修改 const修饰的迭代器(只读)&#xff1a; 反向迭代器&#xff1a; reserve与resize&#xff1a; find&#xff0c;rfind&#xff0c;substr&#xff1a; insert&#xff1a; erase&#xff1a; getchar、getline&#xff1a; string对…

Java基础学习笔记(十一)—— 包装类与泛型

包装类与泛型1 包装类1.1 基本类型包装类1.2 Integer类1.3 自动装箱 / 拆箱2 泛型2.1 泛型概述2.2 泛型的用法2.3 类型通配符1 包装类 1.1 基本类型包装类 基本类型包装类的作用 将基本数据类型封装成对象 的好处在于可以在对象中定义更多的功能方法操作该数据 public stat…

✿✿✿JavaScript --- Ajax异步请求与JSONP 跨域请求

目 录 一、原生的Ajax请求 1.异步和同步 2.Ajax介绍 3.实现方式 (1)原生的JS实现方式&#xff08;了解&#xff09; (2)原生AJax发送Post请求&#xff0c;并携带请求参数 二、JQuery封装后的Ajax 1.JQeury实现方式 2. $.get()&#xff1a;发送get请求 3.$.post()&…

存储随笔2022年度最受欢迎文章榜单TOP15

回首2022感谢各位粉丝朋友的一路支持与陪伴存储随笔为您献上2022年度最受欢迎文章榜单TOP152023&#xff0c;一起向未来&#xff01;TOP1&#xff1a;固态硬盘SSD入门级白皮书主要从固态硬盘的原理/接口形态/寿命/使用场景/等不同角度&#xff0c;来对比不同的人群需要什么样的…

[linux]vim编辑器

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;Linux &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要讲解vim的使用和一些vim的常用操作&#xff0c;以及如何解决…

Flow 转 LiveData 后数据丢了,肿么回事?

翻译自&#xff1a; https://arkadiuszchmura.com/posts/be-careful-when-converting-flow-to-livedata/ 前言 最近我在负责一段代码库&#xff0c;需要在使用 Flow 的 Data 层和仍然依赖 LiveData 暴露 State 数据的 UI 层之间实现桥接。好在 androidx.lifecycle 框架已经提供…

C语言-指针进阶-函数指针数组应用-计算器(9.2)

目录 1. 函数指针 2. 函数指针数组 2.1函数指针数组的定义 2.2函数指针数组应用 3. 指向函数指针数组的指针 思维导图&#xff1a; 1. 函数指针 直接上代码&#xff1a; #include <stdio.h>void test() {printf("hehe\n"); }int main() {printf("%…

【Java】数组的复制、反转、查找、排序

数组的复制、反转、查找、排序 复制 其中最关键的一点是搞清楚为什么数组复制和基本数据类型复制不同&#xff0c;是什么导致了这样的不同&#xff1f; 先来看例子 package com.atguigu.java;public class ArrayTest3 {public static void main(String[] args) {//新建arr数…

【Java数据结构与算法】Day2-高级排序(希尔、归并、快速、计数)

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;【Java数据结构与算法】 &#…

实验七:555定时器及其应用

答疑解惑用555定时器组成的单稳态电路中&#xff0c;若触发脉冲宽度大于单稳态持续时间&#xff0c;电路能否正常工作&#xff1f;如果不能&#xff0c;则电路应做如何修改&#xff1f;答:若触发脉冲宽度大于单稳态持续时间后&#xff0c;输出脉冲宽度将等于触发脉冲的低电平持…

【精】EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格

【精】EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格 &#x1f345;因发布平台差异导致阅读体验不同&#xff0c;将本文原编写地址贴出&#x1f339;&#xff1a;《【精】EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格》 文章目录【精】EditorConfig 小老鼠…

实时数仓方案

2、实时数仓方案 2.1、为何需要实时数仓架构 随着数据量的增大&#xff0c;传统数据的方案在时效性上和数据维护上变得越来越困难。实时数仓架构应运而生。 具体方案落地上实时数仓有很多方案可以选择&#xff0c;不同的业务和应用场景到底应该选择哪种技术方案&#xff1f;…

React18新特性

React 团队在 2022 年 3 月 29 日正式发布了 React 的第 18 个版本。 在这篇文章里简单介绍 React 18 的新特性&#xff0c;React Concurrent Mode&#xff08;并发模式&#xff09;的实现&#xff0c;以及简要的升级指南。 New Features Automatic Batching 早在 React 18 之…

011-Ensp-实验-配置ACL

实验要求 1.通过ACL 使PC1无法访问PC3 实验结构 实验步骤 基础环境配置: PC间互通 1. PC1 2 3 配置IP网关 2. LSW2 创建三个vlan &#xff0c;g0/0/2 g0/0/3 g/0/04 类型配置为Access 分别加入三个vlan g0/0/1 配置为trunk 并允许所有vlan通过 3. LSW1 g0/0/1 配置trunk …

vector底层实现及深层次拷贝问题

目录 大框架 接口实现 深层次拷贝问题&#xff08;两次深拷贝&#xff09; 大框架 为了与库里实现的更接近一些&#xff0c;先来看一下STL中是如何实现vector的&#xff08;这里不是PJ版&#xff0c;PJ版稍微晦涩一点不容易理解&#xff0c;这里采用Linux下g的版本&#xf…

VectorNet: Encoding HD Maps and Agent Dynamics from Vectorized Representation

Paper name VectorNet: Encoding HD Maps and Agent Dynamics from Vectorized Representation Paper Reading Note URL: https://arxiv.org/pdf/2005.04259.pdf TL;DR waymo 出品的 CVPR2020 论文 &#xff0c;关注在自动驾驶场景&#xff08;复杂多智能体系统&#xff0…

【算法自由之路】快慢指针在链表中的妙用(下篇)

【算法自由之路】快慢指针在链表中的妙用&#xff08;下篇&#xff09; 继上篇之后&#xff0c;链表这块还有两个相对较难的问题我们继续举例。 问题 1 给定具有 random 指针的 next 方向无环单链表&#xff0c;复制该链表 单听这个问题可能有点懵&#xff0c;这个链表结构我…

PCB封装创建(CHIP类)

PCB封装要有以下内容 PCB焊盘管脚序号丝印阻焊1脚标识目录 CHIP类&#xff08;电阻 电容 电感 三极管&#xff09; 0805C 0805R 0805L SOT-23 1.CHIP类&#xff08;电阻 电容 电感 三极管&#xff09; 1.新建一个PCB元件库 打开PCB Library 以下以0805为例。 创建080…

“CAcModuleResourceOverride”: 未声明的标识符

本文迁移自本人网易博客&#xff0c;写于2011年10月8日首先是运行时提示&#xff1a;试图执行系统不支持的操作。添加CAcModuleResourceOverride resourceOverride; 后&#xff0c;编译出现如下错误&#xff1a;error C2065: “CAcModuleResourceOverride”: 未声明的标识符 添…