当前位置: 首页 > article >正文

C语言字符函数,字符串函数以及内存函数

那么博主写这一片博客的目的就是为下一篇c++的string类做铺垫,那么下面就请期待博主的下一篇文章吧。 

目录

1.字符函数

2.字符串函数(均在string.h头文件中)

strlen的使用和模拟实现

strcpy 的使用和模拟实现 

 strcat 的使用和模拟实现

 strcmp的使用和模拟实现

 strncpy 函数的使用

strncat 函数的使用

strncmp函数的使用

 strstr 的使用和模拟实现

strtok函数的使用

 strerror 函数的使用

3.C语言内存函数

memcpy使用和模拟实现

 memmove使用和模拟实现(可以实现自己给自己追加)

 memset函数的使用

 memcmp函数的使用


1.字符函数

        C语言标准库中的字符处理函数主要是在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;//小写字母与大写字母之间的ASCII值相差32。

        putchar(c);

         i++;

}

        return 0;

}

那么字符函数咱们就不过多的阐述了。下面看字符串函数。

2.字符串函数(均在string.h头文件中)

strlen的使用和模拟实现

size_t  strlen (const char*str) 

       1.  字符串以  '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含'\0')

       2. 参数指向的字符串必须要以 '\0' 结束。

       3. 注意函数的返回值为size_t,是无符号的

         4.strlen的使用需要包含头文件

那么下面咱们来看strlen的模拟实现,下面我提供了三种实现方式:

int my_strlen(const char * str)

{

        int count = 0;

        assert(str);

        while(*str)

{

        count++;

        str++;

}

        return count;

}//这个得引入一个新变量

int my_strlen(const char * str)

{

        assert(str);

        if(*str == '\0')

        return 0;

        else

        return 1+my_strlen(str+1); 

}//采用递归的方式

int my_strlen(char *s)

{

        assert(str);

        char *p = s;

        while(*p != '\0' )

{

        p++;

}

        return p-s; 

}//采用指针减指针的方式,这个方法在C语言指针这一篇博客有讲解

OK,下面进入六个函数的讲解

strcpy 的使用和模拟实现 

char *strcpy  (char*destination,const char*source)

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

2.会将源字符串中的 '\0' 拷贝到目标空间。

 3.目标空间必须足够大,以确保能存放源字符串。

4. 目标空间必须可修改 

5.从源头开始拷贝。

但是这样你打印的话,只能打印出来“xxx”,因为,打印自动到'\0'停止,所以你打印不出完整的拷贝后的字符串,不过可以通过调试观察。

以上也是strcpy函数的模拟实现。

思路:

1.由于返回起始空间的地址,所以要先保存起始空间的地址,防止后面++后,找不到起始空间的地址了。

2.接着断言,防止p与p1指针传的是无效地址。

3.然后把p1指向的字符串中的字符挨个拷贝到p指向的字符串中,之后p1指向的字符串中的字符位置与p指向的字符串中的位置都往后挪动一位。依次重复。

 strcat 的使用和模拟实现

char*strcat  (char*destination,const char*source)

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

 2.目标字符串中也得有 \0 ,否则没办法知道追加从哪里开始。

3. 目标空间必须有足够的大,能容纳下源字符串的内容。

4. 目标空间必须可修改。 

5.destination中的'\0'也会被覆盖

以上是strcat的模拟实现,需要注意的是这里不可以自己给自己追加,否则会导致未定义。

思路:

1.首先先断言一下,由于这里传的是起始空间的地址,所以还要创建一个变量,用来存储起始地址。

2.之后先去找destination中的'\0',找到之后,就从这开始拷贝即可,需要注意的是,source中的'\0'也会别拷贝到目标字符串中。

 strcmp的使用和模拟实现

int   strcmp  (const char*str1,const char*str2)

其实这个函数就是一个用于比较字符串大小的工具。 

1.第⼀个字符串大于第二个字符串,则返回大于0的数字 ◦

2.第⼀个字符串等于第二个字符串,则返回0 ◦

3.第⼀个字符串小于第二个字符串,则返回小于0的数字 ◦

4.那么如何判断两个字符串?比较两个字符串中对应位置上字符ASCII码值的大小。

下面看strcmp函数的模拟实现:

不过要注意的是这里博主用的编译器是vs,并且返不返回1,-1,0,纯看编译器,有的编译器就是不返回这几个数字。

模拟实现代码思路:

1.还是老样子先断言,之后从第一个字符的ASCII值开始比较。

2.如果第一个字符相等,那么++,继续往后比较,如果比较完了,直到最后一个标识字符'\0'都相等,那么就返回0.

3.如果第一个字符串的第一个字符比第二个字符串的第一个字符大,那么就返回1(vs下),否则返回-1.

以上三个函数都是长度不受限制的,那么下面看3个长度受限制的。

 strncpy 函数的使用

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

1.拷贝num个字符(不是字节)从源字符串到目标空间。

2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加'\0'(可通过调试观察),直到num个 。

该函数就是strcpy函数的减缩版,模拟实现方式差不多,这里就不做演示了。

strncat 函数的使用

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

1.将source指向字符串的num个字符追加到destination指向的字符串末尾,再追加⼀个'\0'字符。

很细节,方便打印 

2.如果source 指向的字符串的长度小于num的时候,它不会像strncpy一样,在后面追加'\0',而是直接不管,直接在destination的字符串末尾加一个'\0'即可。

strncmp函数的使用

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

比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字母,如果提前发现不⼀ 样,就提前结束,大的字符所在的字符串大于另外⼀个。如果num个字符都相等,就是相等返回0。 (就是比strcmp函数多了个限制条件)

 strstr 的使用和模拟实现

strstr的作用是用来查找子串的。

char * strstr   ( const char * str1, const char * str2);

1.函数返回字符串str2在字符串str1中第一次出现的位置。

2.字符串的比较匹配不包含 '\0' 字符,以 '\0 '作为结束标志。

来看它的模拟实现吧。

思路:

1.首先先断言一下,因为要返回起始空间的地址,所以说要创建一个变量存放起始地址。

2.先来一个循环,条件是找的时候第一个字符串!='\0',之后,将指向第一个字符串的指针再赋值给s1,指向第二个字符串的指针再赋值给s2,之后便可以开始比较了。

3.如果说找到了s1跟s2相等的字符,那么各自++,继续往后比较,但凡有一个字符不相等了,直接退出循环,cur++,(即返回第一个字符串的起始地址,并且加一,让它从第一个字符串的第二个字符开始比较)。

4.如果说,比较完了,而且正好发现了第一个字符串中藏了第二个字符串,就是到了if阶段,那么这时候,s2就到了'\0'的位置,这时候直接返回当时找的第一个字符串的起始地址即可。

5.不过这里需要注意的是,你打印的时候,是会遇到'\0'才会停止的,所以说,比如,第一个字符串“abcdef”,第二个字符串“cde”,那么可以打印出cdef。

strtok函数的使用

1.sep参数指向⼀个字符串,定义了用作分隔符的字符集合 

2.第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标 记。

 3.strtok函数找到str中的下⼀个标记,并将其用 \0 结尾,返回⼀个指向这个标记的指针。

(注: strtok函数会改变被操作的字符串,所以被strtok函数切分的字符串⼀般都是临时拷贝的内容并且可修改。)

 4.strtok函数的第⼀个参数不为 中的位置。 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串

 5.strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标 记。

 6.如果字符串中不存在更多的标记,则返回 NULL 指针

 strerror 函数的使用

char* strerror ( int errnum );

strerror 函数可以把参数部分错误码对应的错误信息的字符串地址返回来。 在不同的系统和C语言标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头文件中说明 的,C语言程序启动的时候就会使用⼀个全局的变量errno来记录程序的当前错误码,只不过程序启动 的时候errno是0,表示没有错误,当我们在使用标准库中的函数的时候发⽣了某种错误,就会将对应 的错误码,存放在errno中,而⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都 是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回 。

3.C语言内存函数(也在string.h头文件中)

memcpy使用和模拟实现(覆盖原理)

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

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

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

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

4.对于重叠的内存,交给memmove来处理。

来看它的模拟实现

思路:

1.由于也是返回起始空间的地址,所以说先定义一个临时变量,用来存储起始空间的地址,之后再断言。

2.以count--为循环条件,决定了要拷贝的次数,并且让source中的字符拷贝到destination中,一个字符拷贝完之后,++,直到count被减完,才停止赋值。

 memmove使用和模拟实现(可以实现自己给自己追加)

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

其实memmove的用法与memcpy基本一样,就以下不同点:

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

 2.如果源空间和目标空间出现重叠,就得使用memmove函数处理。 

来看它的模拟实现:

 memset函数的使用

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

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

 memcmp函数的使用

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

比较从ptr1和ptr2指针指向的位置开始,向后的num个字节 ,这个其实也是比较类的函数,与strcmp,strncmp差不多。

下面来看它的返回值:

再来看一个例子:

相信大家对这个函数也已经理解了吧。

以上内容是我个人理解,若有不对,还请指出!谢谢!

本篇完...............


http://www.kler.cn/a/599439.html

相关文章:

  • 【漫话机器学习系列】158.均匀分布(Uniform Distribution)
  • Android Compose框架的值动画(animateTo、animateDpAsState)(二十二)
  • macOS 安装 Miniconda
  • 新能源智慧灯杆的主要功能有哪些?
  • Extend module 01:Keyboard
  • STM32学习笔记之常用外设接口(原理篇)
  • 8.BST的缺陷解决方案:平衡树*****
  • 什么是索引?为什么要使用B树作为索引数据结构?
  • 股指期权最后交易日是哪一天?
  • Flask(一)概述与快速入门
  • 蓝桥杯备考:学会使用方向向量
  • Pyserial库使用
  • HRP方法全文总结与模型流程解析
  • Flutter 输入组件 Radio 详解
  • Blender4.4正式发布:核心更新与渲染101云渲染平台应用指南
  • TCP/IP协议的三次握手和四次挥手
  • 《大语言模型赋能证券业开发安全:海云安技术方案在上交所专刊发表》
  • spring boot项目中Lombok注解失效问题
  • 初阶数据结构(C语言实现)——6.2选择排序详解(思路图解+代码实现)
  • 机器学习之回归