C语言进阶第六课-----------字符分类函数和内存的开辟

news2025/1/14 1:17:02

作者前言

🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂
​🎂 作者介绍: 🎂🎂
🎂 🎉🎉🎉🎉🎉🎉🎉 🎂
🎂作者id:老秦包你会, 🎂
简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂
喜欢学习C语言和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨 🎂🎂🎂🎂🎂🎂🎂🎂
🎂个人主页::小小页面🎂
🎂gitee页面:秦大大🎂
🎂🎂🎂🎂🎂🎂🎂🎂
🎂 一个爱分享的小博主 欢迎小可爱们前来借鉴🎂


字符和内存

  • **作者前言**
  • 字符分类函数
    • iscntrl
    • isspace
    • isdigit
    • isxdigit
    • islower
    • isupper
    • isalpha
    • isalnum
    • ispunct
    • isgraph
    • isprint
  • 字符转换
    • toupper
    • tolower
  • 内存相关函数
    • memcpy
    • memove
    • memset
    • memcmp
  • 总结

字符分类函数

iscntrl

在这里插入图片描述
判断对应的ASCII值所对应的字符是否为控制字符
在ASCII码中,第0~31号及第127号(共33个)是控制字符或通讯专用字符,
如果 c 确实是控制字符,则与零(即 true)不同的值。否则为零(即假)。(是控制字符返回非0,不是就返回0)

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
	int i = 0; 
	for (i = 0; i < 50; i++)
	{
		if (iscntrl(i))
			printf(" %d %c:是控制字符\n", i, i + 1);
		else
			printf("%d %c:不是控制字符\n", i, i + 1);
		
	}


	return 0;
}

isspace

判断是否为空白字符
空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
在这里插入图片描述
如果 c 确实是一个空格字符。返回非0(true), 否则为零(即假)。
在这里插入图片描述

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
	int i = 9;
	printf("%d", isspace(i));
	return 0;
}

isdigit

判断字符是否是0-9

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
	int ch;
	ch = getchar();
	if (isdigit(ch))
	{
		printf("%c是数字", ch);
	}
	else
	{
		printf("NO");
	}

	return 0;
}

在这里插入图片描述
十进制数字是以下任意一种: 0 1 2 3 4 5 6 7 8 9 有

isxdigit

判断字符是否为十六进制的字母(包含大小写)和数字
十六进制数字是以下任意一种: 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
在这里插入图片描述
是十六进制数就返回非0的数字,否则就返回0;

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	int i = 48;
	for (; i < 128; i++)
	{
		if (isxdigit(i))
		{
			printf("%c\n", i);
		}
	}
	
	return 0;
}

在这里插入图片描述

islower

在这里插入图片描述
小写字母是以下任意字母:a b c d e f g h i j k l m n o p q r s t u v w x y z。
如果是小写字母就返回非0的数字,否则就返回0

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	int i = 97;
	for (; i <= 122; i++)
	{
		if (islower(i))
		{
			printf("%c\n", i);
		}
	}
	return 0;
}

isupper

判断字符是否是大写字母
在这里插入图片描述
大写字母为以下任意字母:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z。
如果是大写字母就返回非0的数字,否则就返回0

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	int i = 65;
	for (; i <= 95; i++)
	{
		if (isupper(i))
		{
			printf("%c\n", i);
		}
	}
	return 0;
}

isalpha

判断字符是否为字母(包含大小写)
在这里插入图片描述
如果是字母就返回非0的数字,否则就返回0

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	int i = 65;
	for (; i <= 122; i++)
	{
		if (isalpha(i))
		{
			printf("%c\n", i);
		}
	}
	return 0;
}

isalnum

判断字符是否是字母或者数字
如果是字母或者是数字就返回非0的数字,否则就返回0
在这里插入图片描述

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	int i = 48;
	for (; i <= 122; i++)
	{
		if (isalnum(i))
		{
			printf("%c\n", i);
		}
	}
	return 0;
}

ispunct

在这里插入图片描述
检查字符是否为标点字符
如果是标点字符就返回非0的数字,否则就返回0
在这里插入图片描述

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	printf("%d", ispunct('"'));
	return 0;
}

isgraph

在这里插入图片描述
判断字符是否具有图形表示
具有图形表示的字符是除空格字符 (’ ') 之外的所有可以打印的字符(由 isprint 确定)。

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	char arr[] = "abcdefg k";
	char* pa = arr;
	while (*pa)
	{
		if (isgraph(*pa))
		{
			printf("%c", *pa);
		}
		pa++;
	}
	return 0;
}

isprint

在这里插入图片描述
检查 c 是否为可打印字符
可打印字符是在显示器上占据打印位置的字符(这与控制字符相反,使用 iscntrl 检查)。

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	char arr[] = "abcdefg k";
	char* pa = arr;
	while (*pa)
	{
		if (isprint(*pa))
		{
			printf("%c", *pa);
		}
		pa++;
	}
	return 0;
}

注意这里空格也是符合条件的

字符转换

前面我们只是理解了判断字符,如果要转换字符也有对应的库函数

toupper

在这里插入图片描述
小写字母是以下任意字母:a b c d e f g h i j k l m n o p q r s t u v w x y z,分别翻译为:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z。

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	int i = 97;
	for (; i <= 122; i++)
	{
		printf("%c\n", toupper(i));
	}
	return 0;
}

如果是小写就转换,不是就不转换

tolower

同理这个函数就是把大写转换成小写

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int main()
{
	int i = 65;
	for (; i <= 90; i++)
	{
		printf("%c\n", tolower(i));
	}
	printf("%c\n", tolower('a'));
	return 0;
}

如果是大写就转换,不是就不转换

内存相关函数

memcpy

前面我们已经学习过了strcpy,这个函数只适合于字符串拷贝,如果要拷贝整数数组,浮点型数组就会没办法,但是memcpy就可以解决

在这里插入图片描述
这个函数有三个参数,一个是目标空间,一个是起始地址,以及要拷贝的字节总大小
如果看过我模拟出来的qsrot函数就会明白,这里为啥要拷贝字节总大小,我们只把对应的字节大小进行拷贝过去

include<stdio.h>

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

如果我们要模拟实现出来

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<assert.h>

void* my_memcpy(void* destintion, const void* soured, size_t num)
{
	//不为空
	assert(destintion && soured);
	//一个一个字节进行拷贝,要使用char*, 加1访问一个字节
	 const char* su = soured;
	 char* de = destintion;
	 while (num)
	 {
		 *de++ = *su++;
		 num--;
		
	 }
	 return destintion;
}




int main()
{
	char arr[20] = "abcd\0f";
	char arr1[10] = { 0 };
	my_memcpy(arr1, arr, sizeof(arr[0]) * 10);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%c ", arr1[i]);
	}

	return 0;
}

如果当我们使用这个模拟函数进行自身部分的拷贝就会发现,和库函数memcpy有差异

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<assert.h>
int main()
{
	int arr[20] = {1,2,3,4,5,6,7,8,9};
	
	memcpy( arr + 2, arr, sizeof(arr[0]) * 5);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

库函数的结果
在这里插入图片描述
我们模拟函数的结果:
在这里插入图片描述
可以看出两者的差异
看到这里就会有疑问,是不是模拟错了?
其实标准值规定,memcpy来实现不重叠的内存拷贝,而重叠的内存拷贝一般不使用memcpy而是使用memmove,就好比我们考试只需考60分,90分就要其他人去考吧,而我们却发现memcpy连重叠的拷贝也能做到,这就是超预期了,而我们模拟出来的函数只是具备了拷贝不重叠的内存拷贝功能,vs的库函数memcpy两者具备,但是在一些编译器里就会不一定两种功能都有。

memove

在这里插入图片描述
从这里可以看出memmove函数的参数和memcpy是一样的,所以memove函数具备了memcpy的所有功能

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<assert.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	int arr1[10] = { 0 };
	memmove(arr1, arr, sizeof(arr[0]) * 9);
	return 0;
}

我们来模拟一下
在这里插入图片描述
如果模拟这个函数很容易就会把memcpy的功能加上重叠的功能,重叠的方法很多人就会想到我要重新开辟一块临时空间存放和arr一样的,然后进行一一的拷贝,然后再覆盖原来的arr,这个方法是可行的,但是这样很麻烦,那有没有在一个数组内就可以进行拷贝呢?答案是有的
如上图
如果我们要3-7拷贝到1-5的位置上去,我们可以先把3拷贝到1然后依次往下,就可以解决原来数字被覆盖的问题,
如果我们要把1-5拷贝到5-9的位置我们就先拷贝5到9的位置上去,往后依次往前

#include<stdio.h>
void* my_memmove(void* arr1, const void* arr, size_t num)
{
	char* pa1 = arr1;
	const char* pa = arr;
	// 后往前拷贝
	if (pa1 > pa)
	{
		pa1 += num - 1;
		pa += num - 1;
		while (num)
		{
			*pa1 = *pa;
			pa1--;
			pa--;
			num--;
		}
	}
	else
	{
		//前往后拷贝
		while (num)
		{
			*pa1 = *pa;
			pa1++;
			pa++;
			num--;
		}
	}
	return arr1;
}



int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	int arr1[10] = { 0 };
	my_memmove(arr, arr + 2, sizeof(arr[0]) * 5);
	return 0;
}

这里我们要注意一下数组arr的第n个元素的地址是arr+(n - 1)

memset

在这里插入图片描述
填充内存块
把从ptr开始的num个字节填充为value

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdefg";
	memset(arr, 't', 5);
	printf("%s", arr);
	return 0;
}

结果为:
在这里插入图片描述
所以我们可以认为memset是以字节为单位的进行设置的,如果不相信,下面为例

#include<stdio.h>
#include<string.h>
int main()
{
	int arr[10] = { 0 };
	memset(arr, 1, 40);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);

	}
	return 0;
}

结果为:
在这里插入图片描述
在这里插入图片描述
这里就是arr里面 存储的内存,我们的想法是把arr每个元素设置成1,而结果却不对,memset是以字节为单位进行设置的,需要注意一下,在vs是小端存储(高阶数存放在低地址) 结果为01010101
如果我们要模拟实现就是

#include<stdio.h>
#include<string.h>
void* my_memset(void* ptr, int value, size_t num)
{
	char* pr = ptr;
	while (num)
	{
		*pr = value;
		pr++;
		num--;
	}
	return ptr;
}

int main()
{
	char arr[] = "abcdefghij";
	int arr1[5] = { 0 };
	my_memset(arr, '0', sizeof(arr[0]) * 5);
	return 0;
}

memcmp

在这里插入图片描述
比较两个内存块的内容

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9 };
	// 数组的存储方式:01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00
	int arr[] = { 1,2,3,6 };
	// 数组的存储方式:01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00
	printf("%d", memcmp(arr, arr1, 16));
	return 0;
}

在这里插入图片描述
简单的理解,和strcmp的比较方式是一样的,一旦匹配到不相等的内存就会返回
如果不相信还有一个例子

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9 };
	// 数组的存储方式:01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00
	int arr[] = { 1,2,3,0x11223301};
	// 数组的存储方式:01 00 00 00 02 00 00 00 03 00 00 00 01 33 22 11
	printf("%d", memcmp(arr, arr1, 16));
	return 0;
}

我们来模拟一下

#include<stdio.h>
#include<string.h>
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
	while (num)
	{
		if (*((char*)ptr1) == *((char*)ptr2))
		{
			ptr1 = (char*)ptr1 + 1;
			ptr2 = (char*)ptr2 + 1;
		}
		else
		{
			return *((char*)ptr1) - *((char*)ptr2);
		}
			
	}
	return 0;
	


}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	int arr1[] = { 1,2,3,4,5,0x11223306 };
	int num = my_memcmp(arr1, arr, 6);
	printf("%d", num);
	return 0;
}

总结

到这里字符串相关的函数就学习完了,有不懂的可以私聊我

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

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

相关文章

【Python从入门到进阶】39、使用Selenium自动验证滑块登录

接上篇《38、selenium关于Chrome handless的基本使用》 上一篇我们介绍了selenium中有关Chrome的无头版浏览器Chrome Handless的使用。本篇我们使用selenium做一些常见的复杂验证功能&#xff0c;首先我们来讲解如何进行滑块自动验证的操作。 一、测试用例介绍 我们要通过sel…

websocket逆向-protobuf序列化与反序列化

系列文章目录 训练地址&#xff1a;https://www.qiulianmao.com 基础-websocket逆向基础-http拦截基础-websocket拦截基础-base64编码与解码基础-protobuf序列化与反序列化视频号直播弹幕采集实战一&#xff1a;Http轮询更新中 websocket逆向-protobuf序列化与反序列化基础 系…

操作系统 内存对齐

文章目录 内存管理内存对齐为什么需要内存对齐内存对齐的规则举例说明两个函数 内存管理 内存是计算机的重要组成部分&#xff0c;内存是与cpu沟通的桥梁&#xff0c;用来暂存cpu中的运算数据。在早期&#xff0c;程序直接运行在物理内存中&#xff0c;直接操作物理内存&#…

MathType7.5最新版本升级教程

MathType7.5是MathType6.9a的升级版本&#xff0c;这是一款好用的数学公式编辑器&#xff0c;软件支持win、mac等操作系统&#xff0c;可以与各类办公软件兼容&#xff0c;能够快速在office文档中进行各类数学公式、符号的输入和运算等操作&#xff0c;coco玛奇朵小编为大家带来…

LiveGBS流媒体平台GB/T28181常见问题-如何禁用删除已注册设备国标设备如何删除

LiveGBS常见问题-如何禁用删除已注册设备国标设备如何删除 1、禁用删除设备2、找到需要删除的设备3、接入控制黑名单4、配置到黑名单5、删除设备6、搭建GB28181视频直播平台 1、禁用删除设备 有的时候&#xff0c;需要将接入到平台的某些设备禁用&#xff0c;并删除。改如何操…

池化技术在真实业务中的实践

一些废话 作为一名Java开发人员&#xff0c;池化技术或多或少在业务代码中使用。常见的包括线程池、连接池等。也是因为Java语言超级丰富的基建&#xff0c;基本上这些池化能力都有着相对成熟的“工具”。比如&#xff0c;需要使用线程池的时候常常会选择Spring提供的 ThreadP…

DL Homework 4

目录 1 整理一下理论收获 1.1 基础理论 1.2 应用到机器学习 1.3 参数学习 1.4 反向传播算法 2.激活函数 3.神经网络流程推导(包含正向传播和反向传播) 4.数值计算 - 手动计算 5.代码实现 - numpy手推 6.代码实现 - pytorch自动 7.激活函数Sigmoid用PyTorch自带函数torc…

蓝桥杯(七段码,C++)

思路&#xff1a; 1、把灯管的连接转为图结构&#xff0c;相邻的灯管即认为有边。 2、用深度搜索&#xff0c;去计算有多少种不同字符。 3、因为有每种字符都会重复算两遍&#xff0c;最后的结果需要数以2。 #include <iostream> using namespace std;int graph[7][7…

震惊!阿里卷成这样?不吃饭了,上厕所、团建都要聊工作,人均上厕所小于一天三次...

上一篇&#xff1a;雷军被小米封号 你敢相信吗&#xff1f;最近一篇名为《坐标阿里 我们组已经不吃饭了》的帖子在大厂社区上引发热议。 作者爆料&#xff1a;坐标阿里&#xff0c;组里已经卷到不吃饭了&#xff0c;之前卷到上厕所要聊工作、团建都要聊工作&#xff0c;现在已经…

B2R靶机渗透

B2R靶机渗透 视频参考&#xff1a;ajest &#xff1a;https://www.zhihu.com/zvideo/1547357583714775040?utm_id0 原文参考&#xff1a;ajest &#xff1a;https://www.zhihu.com/column/c_1403138803561816064 文章目录 B2R靶机渗透1 启动靶机&#xff0c;查看后网卡为ma…

数据特征选择 | Lasso特征选择(Python)

文章目录 效果一览文章概述源码设计小结效果一览 文章概述 Lasso算法是一种经典的线性回归算法,被广泛应用于特征选择和降维问题。相较于传统的线性回归算法,Lasso算法能够在保持预测准确性的同时,自动筛选出对目标变量影响较大的特征变量,从而达到降低模型复杂度、提高泛化…

CSS悬停卡片翻转明信片效果源码附注释

运行效果演示: HTML页面代码: <!DOCTYPE html> <html lang="en" > <head>

kafka安装步骤以及初步入门

安装Java sudo apt install default-jdk # 执行完直接直接查看版本就好了 java -versionhttps://blog.csdn.net/CyberSparkZ/article/details/132441191 安装zookeeper https://blog.csdn.net/supercrsky/article/details/124570611 https://blog.csdn.net/xiaozhang_man/ar…

为什么大多数企业开始转型做私域?

随着互联网的迅猛发展&#xff0c;越来越多的企业纷纷选择转型做私域电商。下面是十大理由&#xff0c;说明为什么大多数企业开始转型做私域。 一、提高用户黏性 通过私域化经营&#xff0c;企业能够更好地掌握用户信息和行为习惯&#xff0c;建立用户数据库&#xff0c;并利…

206、SpringBoot 整合 RabbitMQ 的自动配置类 和 对应的属性处理类 的知识点

目录 ★ Spring Boot 为 RabbitMQ 提供的自动配置▲ 自动配置类&#xff1a;RabbitAutoConfiguration▲ 属性处理类&#xff1a;RabbitProperties相关配置 ★ AmqpAdmin的方法★ AmqpTemplate的方法代码演示创建一个springboot的项目。application.properties 配置属性 ★ Spri…

JavaScript发布—订阅模式

JavaScript发布—订阅模式 1 什么是发布—订阅模式2 DOM 事件3 实现一个发布—订阅模式4 发布—订阅模式的通用实现5 取消订阅的事件6 全局的发布—订阅对象7 模块间通信 1 什么是发布—订阅模式 发布—订阅模式又叫观察者模式&#xff0c;它定义对象间的一种一对多的依赖关系…

第五十六章 学习常用技能 - 执行 SQL 查询

文章目录 第五十六章 学习常用技能 - 执行 SQL 查询执行 SQL 查询检查对象属性 第五十六章 学习常用技能 - 执行 SQL 查询 执行 SQL 查询 要运行 SQL 查询&#xff0c;请在管理门户中执行以下操作&#xff1a; 选择系统资源管理器 > SQL。如果需要&#xff0c;请选择标题…

Servlet与设计模式

1 过滤器和包装器 过滤器可以拦截请求及控制响应&#xff0c;而servlet对此毫无感知。过滤器有如下作用&#xff1a; 1&#xff09;请求过滤器&#xff1a;完成安全检查、重新格式化请求首部或体、建立请求审计日志。 2&#xff09;响应过滤器&#xff1a;压缩响应流、追加或…

softmax激活函数

Softmax激活函数是一种用于多类别分类问题的激活函数&#xff0c;通常用于神经网络的输出层。它将原始分数&#xff08;也称为logits&#xff09;转换为表示概率分布的数值&#xff0c;使得每个类别的概率值都在0和1之间&#xff0c;并且所有类别的概率之和等于1。这使得它适用…