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

相关文章

Pandas中统计汇总可视化函数plot()的使用

《Pandas中统计汇总可视化函数plot()的使用》Pandas提供了许多强大的数据处理和分析功能,其中plot()函数就是其可视化功能的一个重要组成部分,本文主要介绍了Pandas中统计汇总可视化... 目录一、plot()函数简介二、plot()函数的基本用法三、plot()函数的参数详解四、使用pl

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

利用Python调试串口的示例代码

《利用Python调试串口的示例代码》在嵌入式开发、物联网设备调试过程中,串口通信是最基础的调试手段本文将带你用Python+ttkbootstrap打造一款高颜值、多功能的串口调试助手,需要的可以了... 目录概述:为什么需要专业的串口调试工具项目架构设计1.1 技术栈选型1.2 关键类说明1.3 线程模

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

Python正则表达式语法及re模块中的常用函数详解

《Python正则表达式语法及re模块中的常用函数详解》这篇文章主要给大家介绍了关于Python正则表达式语法及re模块中常用函数的相关资料,正则表达式是一种强大的字符串处理工具,可以用于匹配、切分、... 目录概念、作用和步骤语法re模块中的常用函数总结 概念、作用和步骤概念: 本身也是一个字符串,其中