C语言字符函数和字符串函数以及内存函数(全是代码版):一篇文章让你秒懂基础!

本文主要是介绍C语言字符函数和字符串函数以及内存函数(全是代码版):一篇文章让你秒懂基础!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

JAMES别扣了-CSDN博客(个人主页)

💕在校大学生一枚。对IT有着极其浓厚的兴趣
✨系列专栏目前为C语言初阶、后续会更新c语言的学习方法以及c题目分享.
😍希望我的文章对大家有着不一样的帮助,欢迎大家关注我,我也会回关,大家一起交流一起互动,感谢大家的多多支持哈!

🎉欢迎 👍点赞✍评论⭐收藏

 前言

在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语⾔标准库中提供了 ⼀系列库函数,接下来我们就学习⼀下这些函数。

 1. 字符分类函数

 C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。 这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h

 这些函数的使⽤⽅法⾮常类似,我们就讲解⼀个函数的事情,其他的⾮常类似:

int islower ( int c );

islower 是能够判断参数部分的 c 是否是⼩写字⺟的。 通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。

练习:

#include <stdio.h>#include <ctype.h>int main (){int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (islower(c)) 
c -= 32;
putchar(c);i++;}return 0;}

2. 字符转换函数

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写
上⾯的代码,我们将⼩写转⼤写,是-32完成的效果,有了转换函数,就可以直接使⽤数。#include <stdio.h>#include <ctype.h>int main (){int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (islower(c)) 
c = toupper(c);putchar(c);i++;}return 0;}tolower

3.sizeof和strlen的对⽐

3.1sizeof

在学习操作符的时候,我们学习了 sizeof , sizeof 计算变量所占内存内存空间⼤⼩的,单位是 字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的⼤⼩。

sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据.

比如:

#inculde <stdio.h>int main(){int a = 10;printf("%d\n", sizeof(a));printf("%d\n", sizeof a);printf("%d\n", sizeof(int));return 0;}

 3.2strlen

strlen 是C语⾔库函数,功能是求字符串⻓度。函数原型如下:

 size_t strlen ( const char * str );

统计的是从 strlen 函数的参数 str 中这个地址开始向后, \0 之前字符串中字符的个数。 strlen 函数会⼀直向后找 \0 字符,直到找到为⽌,所以可能存在越界查找。

 #include <stdio.h>int main(){char arr1[3] = {'a', 'b', 'c'};char arr2[] = "abc";printf("%d\n", strlen(arr1));printf("%d\n", strlen(arr2));}printf("%d\n", sizeof(arr1));printf("%d\n", sizeof(arr1));return 0;

3.3sizeof 和strlen的对⽐

sizeof

1. sizeof是操作符

2. sizeof计算操作数所占内存的⼤⼩, 单位是字节

3. 不关注内存中存放什么数据

strlen

1. strlen是库函数,使⽤需要包含头⽂件 string.h

2. srtlen是求字符串⻓度的,统计的是 \0 之前字符的隔个数

3. 关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可 能会越界

4.strlen的使⽤和模拟实现

size_t strlen ( const char * str );

• 字符串以 含 '\0' )。 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包 • 参数指向的字符串必须要以 '\0' 结束。

• 注意函数的返回值为size_t,是⽆符号的

• strlen的使⽤需要包含头⽂件

strlen的模拟实现:

⽅式1:

//计数器⽅式int my_strlen(const char * str){int count = 0;assert(str);while(*str){count++;str++;}return count;}

⽅式2:

//不能创建临时变量计数器int my_strlen(const char * str){assert(str);if(*str == '\0')return 0;elsereturn 1+my_strlen(str+1);}

⽅式3:

//指针-指针的⽅式int my_strlen(char *s){assert(str);char *p = s;while(*p != ‘\0’ )p++;return p-s;}

5.strcpy 的使⽤和模拟实现

• 源字符串必须以 '\0' 结束。

• 会将源字符串中的 '\0' 拷⻉到⽬标空间。

• ⽬标空间必须⾜够⼤,以确保能存放源字符串。

• ⽬标空间必须可修改。

• 学会模拟实现。

strcpy的模拟实现:

//1.参数顺序//2.函数的功能,停⽌条件//3.assert//4.const修饰指针//5.函数返回值//6.题⽬出⾃《⾼质量C/C++编程》书籍最后的试题部分char *my_strcpy(char *dest, const char*src){        
char *ret = dest;assert(dest != NULL);assert(src != NULL);while((*dest++ = *src++)){;}return ret;}

6. strcat 的使⽤和模拟实现

• 源字符串必须以 '\0' 结束。

• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。

• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。

• ⽬标空间必须可修改。

• 字符串⾃⼰给⾃⼰追加,如何?

模拟实现strcat函数:

char *my_strcat(char *dest, const char*src){char *ret = dest;
assert(dest != NULL);assert(src != NULL);while(*dest){dest++;}while((*dest++ = *src++)){;}return ret;}

7.strcmp的使⽤和模拟实现

◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字

◦ 第⼀个字符串等于第⼆个字符串,则返回0

◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

◦ 那么如何判断两个字符串?⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。

strcmp函数的模拟实现:

int my_strcmp (const char * str1, const char * str2){int ret = 0 ;assert(src != NULL);assert(dest != NULL);while(*str1 == *str2){if(*str1 == '\0')return 0;str1++;str2++;}return *str1-*str2;}

8.strncpy 函数的使⽤

char * strncpy ( char * destination, const char * source, size_t num );

• 拷⻉num个字符从源字符串到⽬标空间。

• 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。

9.strncmp函数的使⽤

int strncmp ( const char * str1, const char * str2, size_t num );

⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀ 样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0

 10.memcpy使⽤和模拟实现

void * memcpy ( void * destination, const void * source, size_t num );

• 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。

• 这个函数在遇到 '\0' 的时候并不会停下来。

• 如果source和destination有任何的重叠,复制的结果都是未定义的。

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

对于重叠的内存,交给memmove来处理。 memcpy函数的模拟实现:

 void * memcpy ( void * dst, const void * src, size_t count){void * ret = dst;assert(dst);assert(src);/** copy from lower addresses to higher addresses*/while (count--) {*(char *)dst = *(char *)src;dst = (char *)dst + 1;src = (char *)src + 1;}}return(ret);

11.memmove使⽤和模拟实现

void * memmove ( void * destination, const void * source, size_t num );

• 和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。

• 如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。

#include <stdio.h>#include <string.h>int main(){int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr1+2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}return 0;}

 memmove的模拟实现:

void * memmove ( void * dst, const void * src, size_t count){void * ret = dst;if (dst <= src || (char *)dst >= ((char *)src + count)) {/** Non-Overlapping Buffers* copy from lower addresses to higher addresses*/while (count--) {*(char *)dst = *(char *)src;dst = (char *)dst + 1;src = (char *)src + 1;}}else {/** Overlapping Buffers* copy from higher addresses to lower addresses*/dst = (char *)dst + count - 1;src = (char *)src + count - 1;while (count--) {*(char *)dst = *(char *)src;dst = (char *)dst - 1;src = (char *)src - 1;}}return(ret);}

12. memset函数的使⽤

 void * memset ( void * ptr, int value, size_t num );

memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。

#include <stdio.h>#include <string.h>int main (){char str[] = "hello world";memset (str,'x',6);printf(str);return 0;}

13.memcmp函数的使⽤

 int memcmp ( const void * ptr1, const void * ptr2, size_t num );

• ⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节

• 返回值如下:

 

#include <stdio.h>#include <string.h>int main(){char buffer1[] = "DWgaOtP12df0";char buffer2[] = "DWGAOTP12DF0";int n;n = memcmp(buffer1, buffer2, sizeof(buffer1));if (n > 0) 
printf("'%s' is greater than '%s'.\n", buffer1, buffer2);else if (n < 0) 
printf("'%s' is less than '%s'.\n", buffer1, buffer2);else 
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);return 0;}

这篇关于C语言字符函数和字符串函数以及内存函数(全是代码版):一篇文章让你秒懂基础!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/826313

相关文章

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python