C语言:字符函数 字符串函数 内存函数

C语言:字符函数 & 字符串函数 & 内存函数

    • 字符函数
      • 字符分类函数
      • 字符转换函数
        • tolower
        • toupper
    • 字符串函数
      • strlen
      • strcpy
      • strcat
      • strcmp
      • strstr
      • strtok
    • 内存函数
      • memcpy
      • memmove
      • memset
      • memcmp


字符函数

顾名思义,字符函数就是作用于字符的函数,而字符函数主要分为字符分类函数以及字符转换函数

字符分类函数

字符分类函数,用于判断一个字符是否属于某一个类

函数参数符合条件
isntrl任何字符
isspace空白字符,空格'',换页符'\f',换行符'\n',回车符'\r',制表符'\t',垂直制表符'\v'
isdigit十进制数字0 - 9
isxdigit十六进制数字,包括0 - 9a - fA - F
islower小写字母a - z
isupper大写字母A - Z
isalpha字母a - zA - Z
isalnum字母或数字,a - zA - Z0 - 9
ispunct标点符号,任何不属于字母或数字的可打印字符
isgraph任何图形字符
isprint任何可打印字符

对于以上函数,只要传入的字符符合要求,返回非0数字;否则返回0;


字符转换函数

tolower

将传入的大写字母变成小写字母

toupper

将传入的小写字母变成大写字母


字符串函数

strlen

strlen函数用于求出字符串的长度,其判定结束的标志为\0

大部分情况下,\0出现在字符串的结尾,但是如果\0出现在字符串的中间,那么我们就无法得到字符串的正确长度。


strcpy

在这里插入图片描述
strcpy函数用于拷贝字符串,其参数如下:

destination:拷贝后字符串存放的空间
source:字符串的来源

返回值为char*,指向拷贝后的destination,方便链式访问

  • 对于source来说,其结束的标志依然为'\0',其默认带有的'\0'也会被拷贝到指定字符串的末尾。

  • destination必须指向可以修改的空间,并且足以放置source的字符个数。

strncpy是一个与strcpy功能一致的函数,但是其可以限制拷贝字符的个数
对于strcpy,其拷贝字符的个数就是source'\0'之前字符个数。strncpy可以传入第三个参数,用于规定拷贝字符的个数。

示例:

char arr[100] = { 0 };
strncpy(arr, "hello", 3);

以上代码把"hello"的前三个字符”hel“拷贝进了arr中。

另外,如果字符串的长度不足n,那么少的位置会用\0补充


strcat

在这里插入图片描述
strcat函数用于对字符串进行追加,其会把source追加到destination的末尾。所以destinationsource都必须由\0结尾

示例:

char arr[100] = "hello";
strcat(arr, "world");

追加后,arr内部存储的就是helloworld了。

注意事项:

  • C语言标准没有要求此函数可以自追加,这取决于编译器的实现
  • destination必须是可以修改的

同样的,这个函数也有限制长度的版本strncat。第三个参数用于限定追加字符串的长度:当字符串长度超过n,则只追加n个字符;当字符串长度小于n,那么追加完这个字符串就不再追加


strcmp

在这里插入图片描述
此函数用于比较两个字符串的大小

  • str1大于str2,返回大于0的值
  • str1等于str2,返回0
  • str1小于str2,返回小于0的值

比较的是两个字符串的字典序,而非长度。

同样的,该函数存在一个限制长度的版本strncmp,比较两个字符串的前n个字符。


strstr

在这里插入图片描述
此函数用于进行字符串查找,即在str1中查找str2

如果找到了,返回str1中指向str2的指针
如果没找到,返回NULL


strtok

在这里插入图片描述
strtok函数用于对字符串进行分割,其有两个参数:

str:被分割的字符串
delimiters:分隔符组成的字符串

比如delimiters如果是“@#!”,那么这个字符串遇到#@!时就会将字符串进行分隔。

当在字符串中找到了对应的分隔符:

  1. 将这个分隔符改为\0
  2. 返回指向这个字符的指针

如果没找到字符,或者遇到末尾,此时返回NULL

另外地,strtok如果对str传入了NULL,下一次会从上一次更改的地方开始查找

示例:

char arr[100] = "hello!world?cs@dn";
const char* p = "!?@";

for (char* r = strtok(arr, p); r != NULL; r = strtok(NULL, p))
{
	printf("%s\n", r);
}

以上代码中,第一次调用strtok传入了arr,后续都传入NULL,从而完成整个字符串的分隔:
输出结果:

hello
world
cs
dn

内存函数

C语言中的内存函数用于对内存进行操控,主要包括内存的拷贝,初始化,以及内存数据的比较。

memcpy

在这里插入图片描述

函数用于对内存进行拷贝,此函数包含三个参数:

destination:目的地,即拷贝后的数据存入的地方
source:源,即被拷贝的内存
num:字节数

示例:

int arr1[] = { 1,2,3,4,5 };
int arr2[5] = { 0 };

memcpy(arr2, arr1, sizeof(int) * 5);

以上代码,完成了两个数组之间的内存拷贝,拷贝方向为:从arr1拷贝到arr2,共拷贝了sizeof(int) * 5 = 20个字节。

现在我们模拟实现一个memecpy

void* my_memcpy(void* destination, void* source, size_t num)
{
	void* ret = destination;
	assert(destination && source);

	while (num--)
	{
		*(char*)destination = *(char*)source;
		destination = (char*)destination + 1;
		source = (char*)source + 1;
	}

	return ret;
}

可以看到,memcpy的拷贝是以字节为单位,将传入的void*指针转为char*指针,然后一个一个字节进行拷贝。这样这个函数就可以处理任何类型的内存拷贝。

但是这个函数存在一个问题,无法拷贝内存发生重叠的函数

看到以下过程:

int arr[6] = { 1,2,3,4 };

memcpy(arr + 2, arr, sizeof(int) * 4 ;

此代码希望把arr的前四个元素拷贝到后四位去,即:

1 2 1 2 3 4

实际输出结果:

1 2 1 2 1 2

为什么会这样?

看到以下过程:
在这里插入图片描述
我们要把蓝色区域的数值拷贝到红色区域,从左往右拷贝,第一次进行拷贝,由于内存重叠,1 2会把3 4覆盖,导致后续拷贝3 4时拷贝到的还是1 2

C语言标准库没有要求memcpy对重叠的内存进行处理,但是有的编译器可以处理这种情况,有的不可以。
为处理这个情况,C语言有专门的函数memmove用于处理重叠内存的情况。


memmove

memmove函数也用于进行内存拷贝,与memcpy不同的是,C标准规定其可以处理内存的重叠。

示例:

int arr[6] = { 1,2,3,4 };

memmove(arr + 2, arr, sizeof(int) * 4 ;

同样的代码,输出结果为:

1 2 1 2 3 4

这是如何做到的?
其实就是一个简单的拷贝方向的问题:

当我们把以上的重叠拷贝,从右向左拷贝:
在这里插入图片描述
可以看到,虽然发生了内存的重叠,但是我们先把会被覆盖的数据拷贝好,然后再覆盖重叠区域的数据,此时我们的拷贝就正常运行了。

所以memmove的实现中,我们要根据内存的重叠情况,来控制内存的拷贝方向,以保证重叠的数据先被拷贝。

代码如下:

void* my_memmove(void* destination, void* source, size_t num)
{
	void* ret = destination;
	assert(destination && source);

	if (destination < source)
	{
		while (num--)
		{
			*(char*)destination = *(char*)source;
			destination = (char*)destination + 1;
			source = (char*)source + 1;
		}
	}
	else
	{
		while (num--)
		{
			*((char*)destination + num) = *((char*)source + num);
		}
	}

	return ret;
}

destination指针小于source,我们就从低地址向高地址拷贝
destination指针大于source,我们就从高地址向低地址拷贝


memset

在这里插入图片描述
memset函数用于对内存进行初始化,其包含三个参数:

ptr:指向待初始化内存的指针
value:希望内存被初始化的值
num:想要初始化内存的字节数

此函数只能按照字节初始化内存,比如以下代码:

int arr[5] = { 0 };
memset(arr, 1, sizeof(int) * 5);

以上代码并不是把数组中的五个int元素初始化为1,而是把每个字节都初始化为00000001


memcmp

在这里插入图片描述
此函数用于比较内存中的数据,ptr1ptr2是被比较的内存。
其按照字节进行比较,从前往后,一个一个字节比较ASCII码值,当某一对字节的ASCII码值不同,此时该字节ASCII码值大的内存,就是比较大的。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3dgs学习(二)—— 3d高斯与协方差矩阵及其几何意义

协方差矩阵与3d高斯 3d高斯与椭球与协方差矩阵 3d高斯&#xff0c;及3维空间内的正态分布。 通过一元正态分布的坐标系图像不难想象&#xff0c;3维空间中的正态分布点集中在一片椭球空间中&#xff0c;各方向长轴取决于各方向正态分布的方差。 而协方差矩阵通过计算多元之…

好物周刊#42:国产项目管理软件

https://github.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. 菠萝博客 基于 Java 的菠萝博客系统&#xff0c;简单易部署&#xff0c;精致主题&#xff0c;贴心服务&#xf…

本届挑战赛亚军方案:面向微服务架构系统中无标注、多模态运维数据的异常检测、根因定位与可解释性分析

CheerX团队来自于南瑞研究院系统平台研发中心&#xff0c;中心主要从事NUSP电力自动化通用软件平台的关键技术研究与软件研发。 选题分析 图1 研究现状 本次CheerX团队的选题紧密贴合了目前的运维现状。实际运维中存在多种问题导致运维系统的不可用。比如故障发生时&#xff…

【常用】【测速】ptflops库---速度FPS、参数Params、计算复杂度Flops

一、常用名字 中文名字 英文名字 简称 单位 模型参数量 number of parameters. param. (单位B M) 计算复杂度 computational…

【Spring Cloud 进阶】OpenFeign 底层原理解析

参考文章 万字33张图探秘OpenFeign核心架构原理 | 三友SpringCloud OpenFeign源码详细解析Java 代理机制 OpenFeign 是一个精彩的使用动态代理技术的典型案例&#xff0c;通过分析其底层实现原理&#xff0c;我们可以对动态代理技术有进一步的理解。 目录 1. Feign 与 OpenFeig…

VUE3:统计分析页面布局+自适应页面参考

一、布局 <template><div class"container1"><div class"form white"><el-form :inline"true" :rules"rules" :model"queryParams" label-width"80px" ref"querParmRef"><e…

力扣递归:路径总和

思路&#xff1a;此题思路为递归实现&#xff0c;递归思路为&#xff1a;在每层递归的过程中将各个节点的数据记录下来&#xff0c;不断将减少目标数据的值准备进行判断&#xff0c;当进行到叶子节点时要进行判断 /*** Definition for a binary tree node.* struct TreeNode {…

OJ_二叉树最短路径长度

题干 C实现 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> using namespace std;struct TreeNode {int num;TreeNode* left;TreeNode* right;TreeNode* parent; };void createTree(vector<TreeNode*>& nodeArr, int n) {for (i…

2000-2022年上市公司绿色专利申请占比/数据

2000-2022年上市公司绿色专利申请占比数据 1、时间&#xff1a;2000-2022年 2、来源&#xff1a;国家知识产权局、WIPO绿色专利清单 3、指标&#xff1a;年份、股票代码、股票简称、行业代码、省份、城市、区县、行政区划代码、城市代码、区县代码、首次上市年份、上市状态、…

又降价啦!2024年阿里云核心产品价格全线下调,最高幅度达55%

2024年3月1日开始&#xff0c;阿里云将开启新一轮的降价政策&#xff0c;核心产品价格全线下调&#xff0c;平均降幅20%&#xff0c;最高幅度达55%&#xff0c;阿里云希望通过此次大规模降价&#xff0c;让更多企业和开发者用上先进的公共云服务&#xff0c;加速云计算在中国各…

深度学习 精选笔记(8)梯度消失和梯度爆炸

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

备战蓝桥杯Day19 - 堆排序基础知识

一、每日一题 - 填充 详细题解 s input() # 输入字符串 n len(s) # 定义字符的长度 judge ["00", "11", "0?", "1?", "?0", "?1", "??"] # 把所有的情况一一列举出来 count 0 # 设置计数…

【Python】PyGameUI控件

哈里前段时间写了一个windows平板上自娱自乐&#xff08;春节和家人一起玩&#xff09;基于pygame的大富翁游戏。 pygame没有按钮之类的UI控件&#xff0c;写起来不怎么顺手。就自己写一个简单的框架。 仓库地址 哈里PygameUi: pygame ui封装自用 (gitee.com) 使用示例 示…

Tomcat 软件和配置文件 基本介绍

一 &#xff0c;web知识 简介 &#xff08;一&#xff09;web技术 1&#xff0c;http协议和 B/S &#xff08;Browser/Server&#xff09;结构 最早出现了CGl (Common Gateway Interface)通用网关接口&#xff0c;通过浏览器中输入URL直接映射到一个服务器端的脚本程序执行&…

从单体服务到微服务:多模式 Web 应用开发记录<三>预初始化属性

相关文章&#xff1a; 多模式 Web 应用开发记录<一>背景&全局变量优化多模式 Web 应用开发记录<二>自己动手写一个 Struts 开头先看一个简单的例子&#xff0c;这是 ftl 文件的一个表单&#xff1a; <form id"validateForm" action"#&quo…

【程序员是如何看待“祖传代码”的?】《代码的遗产:探索程序员眼中的“祖传代码”》

程序员是如何看待“祖传代码”的&#xff1f; 在程序员的世界里&#xff0c;代码不仅仅是构建软件的基石&#xff0c;它们也承载着历史、智慧和技术的演变。在我的编程生涯中&#xff0c;我遇到过许多神奇而独特的“祖传代码”&#xff0c;这些代码如同古老的魔法书&#xff0…

【C语言】三子棋

前言&#xff1a; 三子棋是一种民间传统游戏&#xff0c;又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏规则是双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#xff0c;率先将自己的三个棋子走成一条线就视为胜利。但因棋盘太小&#xff0c;三子棋在很多时候会出现和…

C++面试常见八股分享

1.unordered_set和set&#xff0c;unordered_map和map的区别 set 和 map 是 C STL 中的两种关联容器&#xff0c;而 unordered_set 和 unordered_map 是 C11 新增的基于哈希表的关联容器。它们之间的主要区别在于底层的数据结构和操作复杂度。 set 和 unordered_set&#xff1…

黑马程序员——接口测试——day05——Request库、Cookie、Session、UnitTest框架

目录&#xff1a; Requests库 Requests库安装和简介设置http请求语法应用案例 案例1案例2案例3案例4Cookie Cookie简介CookieSession认证方式案例5-看演示&#xff0c;此代码不需实现Session Session简介Session自动管理Cookie案例6面试题Cookie和Session区别获取指定响应数据…

云原生架构技术揭秘:探索容器技术的奥秘

云原生的概念和演进都是围绕云计算的核心价值展开的&#xff0c;比如弹性、自动化、韧性&#xff0c;所以云原生所涵盖的技术领域非常丰富。 随着云计算技术的不断发展&#xff0c;云原生架构已经成为了新一代软件开发的重要趋势。本文将为您介绍云原生架构的相关技术&#xf…