【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…...

百望云联合华为发布票财税链一体化数智解决方案 赋能企业数字化升级
随着数据跃升为数字经济关键生产要素,数据安全成为整个数字化建设的重中之重。为更好地帮助企业发展,中央及全国和地方政府相继出台了多部与数据相关的政策法规,鼓励各领域服务商提供具有自主创新的软件产品与服务,帮助企业在合规…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...