【C语言】内存函数介绍
创始人
2024-05-10 17:01:46
0

它们所在的头文件:

(这里出现的arr都为char类型数组)

    • strlen

作用:计算一个字符串的长度

本质:历经千辛找一个 \0 ,找到 \0 就立马停止。(就是找 \0 )

易错:strlen 返回值为 size_t ,易错点

strlen 的模拟实现:

//方法一
#include 
#include int my_strlen(const char* str)
{assert(str != NULL);const char* soc = str;while (*soc++ != '\0'){;}return soc - str - 1;}int main()
{char arr[20] = { 0 };scanf("%s", arr);printf("%d", my_strlen(arr));return 0;
}//方法二
//#include 
//#include 
//
//int my_strlen(const char* str)
//{
//    assert(str != NULL);
//    int count = 0;
//
//    while (*str++ != '\0')
//    {
//        count++;
//    }
//
//    return count;
//
//}
//
//int main()
//{
//    char arr[20] = { 0 };
//    scanf("%s", arr);
//
//    printf("%d\n", my_strlen(arr));
//
//    return 0;
//}//方法三
//#include 
//#include 
//
//int my_strlen(const char* str)
//{
//    assert(str != NULL);
//    
//    if (*str++ != '\0')
//    {
//        return 1 + my_strlen(str);
//    }
//    else
//    {
//        return 0;
//    }
//
//}
//
//int main()
//{
//    char arr[20] = { 0 };
//    scanf("%s", arr);
//
//    printf("%d\n", my_strlen(arr));
//
//    return 0;
//}
//

2、strcpy 和 strncpy

strcpy

格式: strcpy(arr1, arr2);

作用:将源字符串拷贝到目标字符串

核心:

while (*str1 = *str2)

{

;

}

(将arr2的内容全部赋给arr1, 不管arr1里面是什么,只要放的下就行)

一旦知道了其核心,就知道它相关的细节问题:

如上 arr2 的 \0 赋过去时才停止,所以会把 arr2 的 \0 赋过去

就是要注意,目标空间(arr1)够大,放得下 arr1;并且是可修改空间(arr1内容不能是字符常量)

strcpy模拟实现:

#include 
#include 
#include char* my_strcpy(char* str1, const char* str2)
{assert(str1 != NULL);assert(str2 != NULL);while (*str1++ = *str2++){;}}int main()
{char arr1[20] = { 0 };char arr2[20] = { 0 };scanf("%s", arr1);scanf("%s", arr2);my_strcpy(arr1, arr2);printf("%s", arr1);return 0;
}

strncpy

格式:strncpy(arr1, arr2, num);

作用:将源字符串的 num 个字符拷贝到目标字符串

核心内容:

除了返回值,不同在于循环时多了个条件来限制给值

while (num && (*str1++ = *str2++))

{

num--;

}

模拟实现:

#include 
#include char* my_strncmp(char* str1, const char* str2, size_t num)
{assert(str1 != NULL);assert(str2 != NULL);while (num && (*str1++ = *str2++)){num--;}if (num){while (--num){*str1++ = '\0';}}return str1;}int main()
{char arr1[20] = { 0 };char arr2[20] = { 0 };scanf("%s", arr1);scanf("%s", arr2);my_strncmp(arr1, arr2, 3);printf("%s\n", arr1);return 0;
}

3、strcmp 和 strncmp

srtcmp

作用:比较两个字符串对应位置上的字符

格式:strcmp(arr1, arr2);

返回值:(相等比下一个,直到结束)

第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串小于第二个字符串,则返回小于0的数字

若对应字符全都相等,才返回0

(visual stdio中大于0是返回1,小于0返回-1, 其他环境下不一定)

模拟实现 stcmp:

//实现strcmp
#include 
#include int my_strcmp(const char* str1, const char* str2)
{assert(str1 != NULL);assert(str2 != NULL);while (*str1 == *str2){if (*str1 == 0){return 0;}str1++;str2++;}if (*str1 > *str2){return 1;}else{return -1;}/*return *str1 - *str2;*/}int main()
{char arr1[20] = { 0 };char arr2[20] = { 0 };scanf("%s", arr1);scanf("%s", arr2);int ret = my_strcmp(arr1, arr2);printf("%d\n", ret);return 0;
}

strncmp

作用:比较两个字符串 num 个数前的字符

格式:strncmp(arr1, arr2, num);

返回值标准和 strcmp 一样

模拟实现(简易版):

//实现简易strcmp
#include 
#include int my_strncmp(const char* str1, const char* str2, size_t num)
{assert(str1 != NULL);assert(str2 != NULL);while ((*str1 == *str2) && num){if (*str1 == 0){return 0;}str1++;str2++;num--;}if (!num){return 0;}if (*str1 > *str2){return 1;}else if (*str1 < *str2){return -1;}/*return *str1 - *str2;*/}int main()
{char arr1[20] = { 0 };char arr2[20] = { 0 };scanf("%s", arr1);scanf("%s", arr2);size_t num = 0;scanf("%u", &num);int ret = my_strncmp(arr1, arr2, num);printf("%d\n", ret);return 0;
}

4、strcat 和 strncat

strcat

作用:在一个目标字符串后追加字符串

格式:strcat(arr1, arr2);

意思是在 arr1 后追加一个 arr2

etc. arr1 = "abcde"; arr2 = "abc";

strcat (arr1, arr2); 这样的结果是:arr1里的内容变成: abcdeabc\0

strcat(arr1, "abcdef"); (例二)

模拟实现:

//模拟实现 strcat
#include 
#include char* my_strcat(char* str1, const char* str2)
{assert(str1 && str2);char* soc = str1;while (*str1){str1++;}while (*str1++ = *str2++){;}return soc;}int main()
{char arr1[20] = { 0 };char arr2[20] = { 0 };scanf("%s", arr1);scanf("%s", arr2);my_strcat(arr1, arr2);printf("%s", arr1);return 0;
}

strncat

作用:和strcat差不多,在目标字符串后追加一定数目的字符(变得可以控制长度)

格式:strncat(arr1, arr2, 4);

意思是在 arr1 后追加一个 arr2 里的前 4 个字符

etc. arr1 = "abcdef"; arr2 = "abcde";

strncat (arr1, arr2, 4); 这样的结果是:arr1里的内容变成: abcdeabcd\0

strncat(arr1, "abcdef", 5); (例二)

模拟实现 strncat:

//模拟实现 strncat
#include 
#include char* my_strncat(char* str1, const char* str2, size_t num)
{assert(str1 && str2);char* soc = str1;while (*str1){str1++;}while (num-- && (*str1++ = *str2++)){;}return soc;}int main()
{char arr1[20] = { 0 };char arr2[20] = { 0 };scanf("%s", arr1);scanf("%s", arr2);size_t num = 0;scanf("%u", &num);my_strncat(arr1, arr2, num);printf("%s", arr1);return 0;
}

5、strstr

作用:寻找字符串arr1中 是否存在 字符串arr2

格式:strstr(arr1, arr2);

意思是寻找 arr1 里的子字符串 有没有和 arr2 相等的

有 就返回:arr1里 目标字符串的首字符地址 (可能不止存在一个,返回找到的第一个子字符串手字符地址)

etc. arr1 = "abcde"; arr2 = "abc";

strstr(arr1, arr2); 返回的结果是arr1中字符 'a' 的地址

模拟实现:

//简易版
#include 
#include 
#include int my_strncmp(const char* str1, const char* str2, int sz)
{while (sz-- && (*str1 == *str2)){if (0 == sz){return 0;}str1++;str2++;}return 1;}char* my_strstr(const char* str1, const char* str2)
{assert(str1 != NULL);assert(str2 != NULL);size_t sz1 = strlen(str1);size_t sz2 = strlen(str2);if (sz1 < sz2){printf("非法输入\n");}for (int i = 0; i <= sz1 - sz2; i++){char* soc = str2;//abcdef//cdeif (!my_strncmp(str1, soc, sz2)){return str1;}str1++;}return NULL;}int main()
{char arr1[20] = { 0 };char arr2[20] = { 0 };scanf("%s", arr1);scanf("%s", arr2);char* p = my_strstr(arr1, arr2);if (p != NULL){printf("\n\n是否存在:存在\n");printf("\n打印符合要求字符串及后面的全部字符:%s\n", p);}else{printf("\n存在情况:不存在 (null)\n");}return 0;
}

6、strtok

作用:将一串带有特殊符号的字符串分隔开(特殊符号一般指标点如 '.' 、'@' 、' * ' )

etc. zhuzhu@yxr.com

strtok 函数可以将上面字符串分割成 "zhuzhu" ,"yxr", "com"

格式:char*strtok ( char*strToken, constchar*strDelimit );

作用的原理是将特殊字符变为 '\0' ,所以实现得先将特殊字符写成一串字符串,放到一个指针里(等下传参也这样规定)

函数第一个参数为要被分隔的字符串;第二个参数为指向分隔符的指针,实现准备好了穿过指针去就OK

返回值:返回该次 “截剪” 的字符串首元素地址 (如上使用一次strtok,返回字符 'z' 的地址);最后分隔符找完会返回 NULL

细节:因为其作用原理(是将分隔符赋为'\0'),所以会改变传过去的字符串内容,当我们不想一个字符串被改变时,可以先把字符串拷贝一份,再传过去

注意使用一次strtok只是将第一个要分隔的地方进行分隔,相当于还没“剪完”,所以要多次使用 ———> 想到循环

而第二次使用时:

第一个参数只要传 NULL 空指针就好,strtok会记录上次改 \0 的位置,在其后再寻找分隔符(第二次:strtok(NULL, pc) )

(可猜出strtok函数中使用了statistic,以至于一些数据一直存在不被销毁)

基本用法:(基本循环写法)

7、strerror

#include

当程序出现各种错误时,每周错误对应一个数字编码,如果只把数字编码反馈出来给我们看,看不懂反正我不看

而 strerror 相当于一个翻译官,可以将这些数字编码转化,返回一个字符串首元素地址,这串对应的字符串就是我们可以看得懂的错误信息,返回该地址后我们用printf来打印,就可以知道错误信息

头文件:

格式:strerror(errno)

作用:返回错误信息

具体用法:

首先的知道当产生错误后,用时也会产生一个数字编码,而这个数字编码存放在哪里呢?是存放在errno这个变量里

所以使用 strerror 时,我们要到 errno 这个变量里去拿到数字编码,所以格式为 strerror(errno)

etc. printf("%s", strerror(errno) );

8、memcpy

格式:memcpy(arr1, arr2, num);

作用:拷贝源空间到目标空间

一定要注意 num 的单位,字节为单位

所以传num时,num = 1字节 * 类型大小 * 拷贝个数

etc. num = 1 * 4 * 要拷贝整型数的个数

模拟实现初级memcpy:(该版本不能拷贝自身局部内容)

//memcpy 的初级实现(移植性强版本)
#include 
#include void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* soc = dest;while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return soc;}int main()
{/*char arr1[20] = { 0 };char arr2[20] = { 0 };scanf("%s", arr1);scanf("%s", arr2);*/int arr1[20] = { 1, 2, 3, 4, 5 };int arr2[20] = { 6, 7, 8, 9, 10 };size_t num = 0;scanf("%zu", &num);my_memcpy(arr1, arr2, num);/*printf("%s", arr1);*/for (int i = 0; i < 5; i++){printf("%d ", *(arr1 + i));}return 0;
}

9、memmove (与memcpy很相似)

格式:memmove(arr1, arr2, num);

作用:拷贝源空间到目标空间

一定要注意 num 的单位,字节为单位(和memcpy一样)

所以传num时,num = 1字节 * 类型大小 * 拷贝个数

etc. num = 1 * 4 * 要拷贝整型数的个数

模拟实现初级memmove:

//memmove 的初级实现
#include 
#include #define count 1000void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* soc = dest;if (dest < src){while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{while (num--){*((char*)dest + num) = *((char*)src + num);}}return soc;}int main()
{int arr[20] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };size_t num = 0;printf("请输入要移动的字节数:");scanf("%zu", &num);my_memcpy(arr + 2, arr, num);/*printf("%s", arr1);*/for (int i = 0; i < 10; i++){printf("%d ", *(arr + i));}return 0;
}

10、一些常见的字符函数

这些函数直接使用就好了,如果记不住那就去记就好啦(可能可以在一些时候帮忙哦)

相关试题就放到后面再更新咯,大家记得电赞哦,不然晚上会梦见小只因哦(真的,昨天晚上我就梦见了)

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...