【C语言】字符分类函数、字符转换函数、内存函数
前言
之前我们用两篇文章介绍了strlen、strcpy、stract、strcmp、strncpy、strncat、strncmp、strstr、strtok、streeror这些函数
第一篇文章strlen、strcpy、stract
第二篇文章strcmp、strncpy、strncat、strncmp
第三篇文章strstr、strtok、streeror
今天我们就来学习字符分类函数、字符转换函数、内存访问函数
话不多说,我们直接开始
字符分类函数
这些函数需要包含头文件<ctype.h>

例子(islower)
用islower函数作为例子
当字符是小写字母时,返回一个非零的整数,
当不是小写字母时,返回0
int main()
{char ch = 'w';int ret = islower(ch);printf("%d\n", ret);return 0;
}
字符转换函数
int tolower(int a)
int toupper(int b)
一般使用
转换单个字符
int main()
{char ch = 'W';char ret = tolower(ch);printf("%c\n", ret);return 0;
}
转换字符串
int main()
{char arr[] = "HELLO WORLD";int i = 0;while (arr[i]){if (isupper(arr[i])){arr[i] = tolower(arr[i]);}i++;}printf("%s\n", arr);return 0;
}
内存访问函数
我们接下来会学习:memcmp、memmove、memcmp、memset函数
引入
小明提出疑问:
我们之前已经学习了那么多的字符串函数:strlen、strcpy、stract、strcmp、strncpy、strncat、strncmp…为什么还要学习内存函数呢
那是因为,上面的那些函数,操作对象都是字符串,也大多需要用到’\0’
而当我们要对整型数组或者结构体的数组,这时我们在用之前的那些函数就做不到了
下面看一段代码,它能达到我们预想的结果吗
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[5] = { 0 };strcpy(arr1, arr2);return 0;
}
程序警告:
“函数”: 从“int [5]”到“char *”的类型不兼容
“函数”: 从“int [5]”到“const char *”的类型不兼容
原因
上面我们学习过:strcpy函数的参数是:char* dest, const char* src
而下面这行代码:
strcpy(arr1, arr2);
就是在把一个整型元素传给一个char*指针的元素
并且,我们知道strcpy在遇到’\0’就停止拷贝以及strcpy的操作单位大小是一个字节
那么如图,整型数据在小端模式下存储的方式如图:

当拷贝完01后,遇到了00,我们都知道’\0’的ASCII码值是0,所以这就相当于拷贝结束,所以对于非字符数组,strcpy是无法使用的
这时,我们就要使用上文提到的内存函数了
memcmp
内存拷贝函数:可以拷贝任何类型的数据
此处联系之前学习的知识,就可以知道参数的类型是void*,
后面的num是需要拷贝的字节数
void * memcpy ( void * destination, const void * source, size_t num );
使用示例
下面介绍两个例子:拷贝整型数据、拷贝结构体类型数据
-struct Stu
{char name[20];int name;
};int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[5] = { 0 };struct Stu arr3[] = { {"zhang", 20}, {"wang", 15},{"li", 25} };struct Stu arr4[] = { 0 };memcpy(arr1, arr2, sizeof(arr1));memcpy(arr3, arr4, sizeof(arr3));return 0;
}
模拟实现
问题:
因为是void*类型的参数,所以我们这里既不能解引用、又不能与整数运算
所以我们就从第三个参数num入手,既然我不知道要拷贝的元素类型是什么,那么就以字节为单位进行拷贝,这样肯定就没问题了
*(char*)dest = *(char*)src;//处理赋值问题
++(char*)dest;//处理运算问题++(char*)src;
初步代码
void* my_memcpy(void* dest, const void* src, int num)
{assert(dest && src);//断言好习惯void* ret = dest;//存储首元素,方便拷贝之后打印while (num--){*(char*)dest = *(char*)src;++(char*)dest;//强制类型转换的优先级比++要低,所以++要写在前面++(char*)src;}return dest;
}
一些重点提示

特殊使用
在下面这个字符串中,我想要将1,2,3,4,5拷贝到3,4,5,6,7的位置上,怎么实现呢(使用my_memcpy函数)
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
像下面这么写可以吗?
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;my_memcpy(arr1 + 2, arr1, 20);for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
运行结果:

咦?那这是为什么?
原因
初步说明:
源数据和目的地数据有关系:当想将3复制到5的地址处时,3已经在之前被替换成1了,所以结果就不对
解决方法
那么如果我们从后向前复制,是不是就可以解决了,先将5复制到7,4复制到6,以此类推
但这种方法也是有漏洞的,当要拷贝的源数据,在目的地数据之前时,程序也会出问题
所以,要根据实际情况来判断,但是有另外的函数来处理这种重叠拷贝的问题
下面我们就来学习memmove函数
注意
虽然使用memcpy函数去执行上面的操作也是可以实现的
但C语言标准中规定,memcpy函数只用来处理内存不重叠的拷贝
memmove函数是用来处理重叠内存的拷贝的
memmove
void * memmove ( void * destination, const void * source, size_t num );
使用示例
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;memmove(arr1 + 2, arr1, 20);return 0;
}
运行结果:

模拟实现
思路分析
分三种情况讨论
1
dest的地址小于src,也就是dest指向的元素在src指向的元素的左边
就从前向后拷贝
2
dest的地址大于src,也就是dest指向的元素在src指向的元素的右边
就从后向前拷贝
3
拷贝的内容无内存重叠,怎么拷贝都可以
最终代码
此处只提供一种分类方式,还有其他的分类方式,都可以
(就是需要注意在进行整数运算的时候,需要进行强制类型转换)
void* my_memmove(void* dest, const void* src, size_t count)
{assert(dest && src);void* ret = dest;if (dest < src)//从前向后{while (count--){*(char*)dest == *(char*)src;++(char*)dest;++(char*)src;}}else//从后向前{while (count--)//count改变,dest和src就不用改变了{*((char*)dest + count) = *((char*)src + count);}}return ret;
}int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;my_memmove(arr1 + 2, arr1, 20);for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
memcmp
简单了解一下即可
介绍
定义如下
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
num是比较的字节个数
返回值
返回值与strcmp函数的返回值判定方式相同,
如果字符串1小于字符串2,返回值小于0
如果字符串1等于字符串2,返回值为0
如果字符串1大于字符串2,返回值大于0
memset
内存设置函数
介绍
作用:设置缓冲区作为特殊的字符
参数:

dest:目的地,即要修改哪块空间
c:要设置的字符是什么
count:要设置的字符数,单位是字节
使用
int main()
{char arr[10] = "";memset(arr, '#', 10);return 0;
}
运行过程:

注意事项
观察下面这段代码,运行结果是什么?
int main()
{int arr[10] = { 0 };memset(arr, 1, 10);printf("%d\n", arr[0]);return 0;
}
输出结果:

这是因为,参数中count单位是字节
上面的代码是将前十个字节改成了1,也就是十六进制的01 01 01 01
结语
关于函数的介绍到这里就结束了,希望你有所收获
之后我们会学习自定义数据类型:结构体,
我们下篇文章见
相关文章:
【C语言】字符分类函数、字符转换函数、内存函数
前言 之前我们用两篇文章介绍了strlen、strcpy、stract、strcmp、strncpy、strncat、strncmp、strstr、strtok、streeror这些函数 第一篇文章strlen、strcpy、stract 第二篇文章strcmp、strncpy、strncat、strncmp 第三篇文章strstr、strtok、streeror 今天我们就来学习字…...
Deep Learning With Pytorch - 最基本的感知机、贯序模型/分类、拟合
文章目录 如何利用pytorch创建一个简单的网络模型?Step1. 感知机,多层感知机(MLP)的基本结构Step2. 超平面 ω T ⋅ x b 0 \omega^{T}xb0 ωT⋅xb0 or ω T ⋅ x b \omega^{T}xb ωT⋅xb感知机函数 Step3. 利用感知机进行决策…...
测试工具coverage的高阶使用
在文章Python之单元测试使用的一点心得中,笔者介绍了自己在使用Python测试工具coverge的一点心得,包括: 使用coverage模块计算代码测试覆盖率使用coverage api计算代码测试覆盖率coverage配置文件的使用coverage badge的生成 本文在此基础上…...
安卓监听端口接收消息
文章目录 其他文章监听端口接收消息 建立新线程完整代码 其他文章 下面是我的另一篇文章,是在电脑上发送数据,配合本篇文章,可以实现电脑与手机的局域网通讯。直接复制粘贴就能行,非常滴好用。 点击连接 另外,如果你不…...
「Node」下载安装配置node.js
以下是Node.js的下载、安装和配置的全面教程: 下载 Node.js 打开 Node.js 官方网站:Previous Releases在主页上,您会看到两个版本可供选择:LTS(长期支持版本)和最新版(Current)。如…...
NOIP2014普及组,提高组 比例简化 飞扬的小鸟 答案
比例简化 说明 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果。例如,对某一观点表示支持的有1498 人,反对的有 902人,那么赞同与反对的比例可以简单的记为1498:902。 不过,如果把调查结果就以这种…...
【Java】使用Apache POI识别PPT中的图片和文字,以及对应的大小、坐标、颜色、字体等
本文介绍如何使用Apache POI识别PPT中的图片和文字,获取图片的数据、大小、尺寸、坐标,以及获取文字的字体、大小、颜色、坐标。 官方文档:https://poi.apache.org/components/slideshow/xslf-cookbook.html 官方文档和网上的资料介绍的很少…...
根据源码,模拟实现 RabbitMQ - 实现消息持久化,统一硬盘操作(3)
目录 一、实现消息持久化 1.1、消息的存储设定 1.1.1、存储方式 1.1.2、存储格式约定 1.1.3、queue_data.txt 文件内容 1.1.4、queue_stat.txt 文件内容 1.2、实现 MessageFileManager 类 1.2.1、设计目录结构和文件格式 1.2.2、实现消息的写入 1.2.3、实现消息的删除…...
找到所有数组中消失的数(C语言详解)
题目:找到所有数组中消失的数 题目详情: 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1,n] 内。请你找出所以在 [1,n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。 示例1: 输入…...
计算机毕设项目之基于django+mysql的疫情实时监控大屏系统(前后全分离)
系统阐述的是一款新冠肺炎疫情实时监控系统的设计与实现,对于Python、B/S结构、MySql进行了较为深入的学习与应用。主要针对系统的设计,描述,实现和分析与测试方面来表明开发的过程。开发中使用了 django框架和MySql数据库技术搭建系统的整体…...
Unity UI内存泄漏优化
项目一运行,占用的内存越来越多,不会释放,导致GC越来越频繁,越来越慢,这些都是为什么呢,今天从UI方面谈起。 首先让我们来聊聊什么是内存泄漏呢? 一般来讲内存泄漏就是指我们的应用向内存申请…...
学习笔记:Opencv实现图像特征提取算法SIFT
2023.8.19 为了在暑假内实现深度学习的进阶学习,特意学习一下传统算法,分享学习心得,记录学习日常 SIFT的百科: SIFT Scale Invariant Feature Transform, 尺度不变特征转换 全网最详细SIFT算法原理实现_ssift算法_Tc.小浩的博客…...
【golang】接口类型(interface)使用和原理
接口类型的类型字面量与结构体类型的看起来有些相似,它们都用花括号包裹一些核心信息。只不过,结构体类型包裹的是它的字段声明,而接口类型包裹的是它的方法定义。 接口类型声明中的这些方法所代表的就是该接口的方法集合。一个接口的方法集…...
【Linux操作系统】Linux系统编程中的共享存储映射(mmap)
在Linux系统编程中,进程之间的通信是一项重要的任务。共享存储映射(mmap)是一种高效的进程通信方式,它允许多个进程共享同一个内存区域,从而实现数据的共享和通信。本文将介绍共享存储映射的概念、原理、使用方法和注意…...
2235.两整数相加:19种语言解法(力扣全解法)
【LetMeFly】2235.两整数相加:19种语言解法(力扣全解法) 力扣题目链接:https://leetcode.cn/problems/add-two-integers/ 给你两个整数 num1 和 num2,返回这两个整数的和。 示例 1: 输入:num…...
中国剩余定理及扩展
目录 中国剩余定理解释 中国剩余定理扩展——求解模数不互质情况下的线性方程组: 代码实现: 互质: 非互质: 中国剩余定理解释 在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二&#x…...
数据在内存中的存储(deeper)
数据在内存中的存储(deeper) 一.数据类型的详细介绍二.整形在内存中的存储三.浮点型在内存中的存储 一.数据类型的详细介绍 类型的意义: 使用这个类型开辟内存空间的大小(大小决定了使用范围)如何看待内存空间的视角…...
算法修炼Day52|● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组
LeetCode:300.最长递增子序列 300. 最长递增子序列 - 力扣(LeetCode) 1.思路 dp[i]的状态表示以nums[i]为结尾的最长递增子序列的个数。 dp[i]有很多个,选择其中最大的dp[i]Math.max(dp[j]1,dp[i]) 2.代码实现 1class Solution {2 pub…...
使用 HTML、CSS 和 JavaScript 创建实时 Web 编辑器
使用 HTML、CSS 和 JavaScript 创建实时 Web 编辑器 在本文中,我们将创建一个实时网页编辑器。这是一个 Web 应用程序,允许我们在网页上编写 HTML、CSS 和 JavaScript 代码并实时查看结果。这是学习 Web 开发和测试代码片段的绝佳工具。我们将使用ifram…...
百望云联合华为发布票财税链一体化数智解决方案 赋能企业数字化升级
随着数据跃升为数字经济关键生产要素,数据安全成为整个数字化建设的重中之重。为更好地帮助企业发展,中央及全国和地方政府相继出台了多部与数据相关的政策法规,鼓励各领域服务商提供具有自主创新的软件产品与服务,帮助企业在合规…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
