• 内存函数


    上章我们简单介绍了几个字符串函数,这里先补充几个。

     嘿咻咻咻咻咻,鸡汤来咯。

    目录

    1.strtok

    2. strerror  

    3.字符分类函数:

    4.内存函数

    4.1memcpy

    4.2 memmove 

    4.3memcmp

     4.4 memset


    1.strtok

    char * strtok ( char * str , const char * sep );

     这个是cplusplus上的介绍,简单介绍: 

    sep 参数是个字符串,定义了用作分隔符的字符集合。
    第一个参数指定一个字符串,它包含了 0 个或者多个由 sep 字符串中一个或者多个分隔符分割的标 记。
    strtok 函数找到 str 中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
    strtok 函数的第一个参数不为 NULL ,函数将找到 str 中第一个标记, strtok 函数将保存它在字符串 中的位置。
    strtok 函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。
    如果字符串中不存在更多的标记,则返回 NULL 指针。

    如果我们有这样一个字符数组

    char ch[ ] = "abcdefgh.ijk";

    我想要拿到abc,用数组也可以达到我们预想的效果,用strtok也可以拿到,上代码:

    1. #include <stdio.h>
    2. #include <string.h>
    3. int main()
    4. {
    5. char ch[] = "abcdefgh.ijk";
    6. char buff[200];
    7. srtcpy(buff, ch);
    8. const char* p = ".";//可以作为分割符的字符的集合,可以是多个
    9. strtok(buff,p);//这个函数就是一个分割符,把我们的字符串分割成n段
    10. //该函数每次找到p中的其中一个字符(一个标记),就将该字符改成'\0',并返回指向这个标记的指针,这里就是a的地址
    11. //(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
    12. //所以我们用另一个字符数组来拷贝ch
    13. return 0;

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include <stdio.h>
    3. #include <string.h>
    4. int main()
    5. {
    6. char ch[] = "abcdefgh.ijk";
    7. char buff[200];
    8. strcpy(buff, ch);
    9. const char* p = ".";
    10. char* str = strtok(buff, p);//strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。
    11. printf("%s\n", str);
    12. char* str1 = strtok(NULL, p);//第二次使用时保存了上一次使用保存好的位置开始继续查找,然后返回这个字段的启示位置。
    13. printf("%s\n", str1);
    14. return 0;
    15. }

    结果如下:

    2. strerror  

    strerror 返回错误码,所对应的错误信息。

    解释 errnum 的值,生成一个字符串,其中包含一条消息,该消息描述错误条件,就好像库的函数设置为 errno 一样。

    返回的指针指向静态分配的字符串,程序不得修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)。

    拿计算机跑一跑:

     我们传参 0 1 2 3 4都有自己的意义。这里的0 1 2 3 4 都是错误码,比如浏览网站时会看见 404 等。

    3.字符分类函数:

    这里有很多经常使用的库函数:

    iscntrl
    任何控制字符
    isspace                                    
    空白字符:空格 ‘ ’ ,换页 ‘\f’ ,换行 '\n' ,回车 ‘\r’ ,制表符 '\t' 或者垂直制表符 '\v'
    isdigit
    十进制数字 0~9
    isxdigit
    十六进制数字,包括所有十进制数字,小写字母 a~f ,大写字母 A~F
    islower
    小写字母 a~z
    isupper大写字母a~z
    isalpha
    字母 a~z A~Z
    isalnum
    字母或者数字, a~z,A~Z,0~9
    ispunct
    标点符号,任何不属于数字或者字母的图形字符(可打印)
    isgraph
    任何图形字符
    isprint
    任何可打印字符,包括图形字符和空白字符

    4.内存函数

    4.1memcpy

    mem —> memory  记忆,但是在我们计算机语言中一般翻译为内存。

    1. 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
    2. 这个函数在遇到 '\0' 的时候并不会停下来。
    3. 如果sourcedestination有任何的重叠,复制的结果都是未定义的。

    它和strcpy很像,但是不一样。我们strcpy只能拷贝字符串,我们看memcpy的参数,都是void*型的,所以我们可以是任意类型。

    我们用int类型试一试:

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

     memcpy第三个参数的单位是字节,所以我这里写的是40。

    4.2 memmove 

     将数字字节的值从指向的位置复制到目标所指向的内存块。复制就像使用了中间缓冲区一样进行,从而允许目标和重叠。
    指针和目标指针所指向的对象的基础类型与此函数无关;结果是数据的二进制副本。
    该函数不检查源代码中的任何终止空字符 - 它始终精确复制数字字节。
    为避免溢出,目标和参数所指向的数组大小应至少为数字字节。

    可以说memmove是memcpy的一部分。

    它和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的。
    如果源空间和目标空间出现重叠,就得使用 memmove 函数处理。
    我们写一段代码来试试自己给自己拷贝,看看结果如何:
    先看看模拟实现的memcpy:
    1. #include <stdio.h>
    2. #include <string.h>
    3. #include <assert.h>
    4. void* my_memcpy(void* dest, void* src, size_t num)
    5. {
    6. void* ret = dest;
    7. assert(dest);
    8. assert(src);
    9. while(num--)//这里我们一个字节一个字节的交换
    10. {
    11. *(char*)dest = *(char*)src;
    12. dest = (char*)dest + 1;
    13. src = (char*)src + 1;
    14. }
    15. return ret;
    16. }
    17. int main()
    18. {
    19. int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    20. my_memcpy(arr1+2, arr1, 20);
    21. int i = 0;
    22. for (i = 0; i < 10; i++)
    23. {
    24. printf("%d ", arr1[i]);
    25. }
    26. return 0;
    27. }

     再来看看memmove 的结果:

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

    4.3memcmp

    比较从ptr1ptr2指针开始的num个字节

    我们重点来看它的返回值:

     对于strcmp相比,memcmp的参数是不固定的,而strcmp的参数都是const chat* 类型。                 相比之下memcmp功能更加强大。

    我们跑一段代码试试:

    1. #include <stdio.h>
    2. #include <string.h>
    3. int main()
    4. {
    5. char buffer1[] = "DWgaOtP12df0";
    6. char buffer2[] = "DWGAOTP12DF0";
    7. int n;
    8. n = memcmp(buffer1, buffer2, sizeof(buffer1));
    9. if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
    10. else if (n < 0) printf("'%s' is less than '%s'.\n", buffer1, buffer2);
    11. else printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
    12. return 0;
    13. }

     4.4 memset

    顾名思义memset是内存设置函数,这个函数作为补充,想要了解更多,可以查cplusplus.com

    这是未调用memset之前的内存。

     

    这是调用之后的内存。 

  • 相关阅读:
    什么是Web组件(Web Components)?它们的主要部分有哪些?
    backend-alarm
    JavaImprove--Lesson06--正则表达式
    Spring Cloud Gateway + Knife4j 4.3 实现微服务网关聚合接口文档
    TCP 加速小记
    【爬虫作业】使用scrapy爬取菜谱,存入elasticsearch中建立菜谱搜索引擎
    微信小程序中 在xwml 中使用外部引入的 js进行判断计算
    如何将分布式锁性能提升100倍【含面试题】
    java类和对象——static成员与代码块
    远程计算机或设备将不接受连接
  • 原文地址:https://blog.csdn.net/weixin_67807492/article/details/126854656