9-7 常见的内存操作函数 memcpy, memchr, memcmp, memset, memmove

1. memcpy 与 strcpy

        memcpy() 函数与 strcpy() 函数(https://blog.csdn.net/gltzlike/article/details/119445386?spm=1001.2014.3001.5501)用法大致相同。memcpy() 函数将第二个变量的指定数量内存块复制到第一个变量内存块的起始位置,且需要指定复制几个内存块mem 开头的函数都有这个特点,都需要指定操作内存块的数量。(strcpy 函数的操作仅适用于字符串,字符串自带 '\0' 结束标志,不需要指定操作内存块数量)

void TestMemcpy(){

  char string1[] = "ABCDE";
  char* string2 = "FGHIJ";

  memcpy(string1, string2, 4); // string2 复制 4 个字节到 string1 中

  printf("string1: %s\n", string1);  // FGHIE
}

2. memchr 与 strchr

        memchr() 函数与 strchr() 函数(https://blog.csdn.net/gltzlike/article/details/119422102?spm=1001.2014.3001.5501)类似,都是找寻一个字符。区别在于 memchr() 函数在一段内存中查找一个字符,strchr() 函数在一个字符串中查找一个字符。例如代码中 memchr() 可以去 int 类型的数组查找一个字符,虽然结果为 NULL。

void TestMemchr(){
  
  // 从字符串中查找
  char string1[] = "Hello";
  char* temp = memchr(string1, 'l', 5); 
  printf("%s\n", temp);  // llo

  // 从数组中查找
  int a[] = {0,1,2,3,4};
  char* temp2 = memchr(a, 48, 5);  // 48 对应的是ASCII码表中的 '0'
  printf("%s\n", temp2);  // (null)
}

3. memcmp 与 strcmp

        memcmp() 函数可以和 strcmp() 函数(https://blog.csdn.net/gltzlike/article/details/115499373?spm=1001.2014.3001.5501)一样,去比较字符串的大小,但也可以去比较 int 类型的数组大小。但在比较时需注意,一个 int 4 个字节,选择的字节数会影响比较结果

void TestMemcmp(){

  // 比较字符串大小
  char *left = "Hello W";
  char *right = "Hello C";

  printf("%d\n", memcmp(right, left, 7));     // right<left -1
  printf("%d\n", memcmp(left, right, 7));     // left>right 1
  printf("%d\n", memcmp(left, right, 6));     // left=right 0

  // 比较数组大小
  int a[] = {2,2,0,4,5};
  int b[] = {2,2,3,4,5};
  int result = memcmp(a, b, 8);
  printf("a?b: %d\n", result);  // a?b: 0

  int result2 = memcmp(a, b, 9);
  printf("a?b: %d\n", result2);  // a?b: -1
}

        如上述代码所示,a 数组和 b 数组比较前八个字节时,a==b,比较第九个字节时才能发现 a<b。原因在于 memcmp() 函数是一个字节位一个字节位进行数组元素比较的,如下图所示,数组中的第三个元素是从第八个字节位开始存储的(0为起点)。

4. memset

        memset() 函数没有与之对应的 string 兄弟,它的功能是将指定数量内存块(字节)的存储值都设置为某一个值。

void TestMemset(){

  char *a = malloc(5);  // 请求分配 5 个字节

  for (int i = 0; i < 5; ++i) {
    printf("%d, ", a[i]);   // -51, -51, -51, -51, -51,
  }

  memset(a, 0, 5); // 将 5 个字节的值设置为 0
  printf("\n");
  for (int i = 0; i < 5; ++i) {
    printf("%d, ", a[i]);  // 0, 0, 0, 0, 0,
  }

  free(a);
}

5. memmove

        memmove() 函数与 memcpy() 函数类似,参数一致,执行结果在 msvc 和 gcc 编译器下相同。memmove() 也是将第二个变量的内存块复制到第一块内存的起始地址,唯一的不同是 memmove() 函数更适用于第一个变量和第二个变量的内存区域有重叠

void TestMemmove(){

  char str[] = "memmove can be very useful......";
  memmove (str+20,str+15,11);
  puts (str);  // memmove can be very very useful.

  char str2[] = "memmove can be very useful......";
  memcpy(str2+20,str2+15,11);
  puts(str2);  // memmove can be very very useful.
}

图出处:http://c.biancheng.net/cpp/html/156.html

        如上图所示,当第一个变量(userful.....)和第二个变量(very useful)的内存块有重叠时,memmove() 函数可以将第二个变量的值先放入缓冲区,然后再对第一个变量的值进行覆盖。这样做的好处是,以第 20 位的 u 为例,防止 u 没有复制到 25 位时,值就被改写了。这里的矛盾在于,第15位的 v 要复制到第20位 u,第20位 u 要复制到第25位 i,有个前后顺序的问题,应该先将 20位的 u 复制到 25位的 i 上,再把 15 位的 v 复制到 20 位 u 上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. atof(): 将字符串转换为double类型的值。 例如: ```c++ char str[] = "3.14"; double num = atof(str); printf("%f", num); ``` 结果为:3.140000 2. atoi(): 将字符串转换为int类型的值。 例如: ```c++ char str[] = "1234"; int num = atoi(str); printf("%d", num); ``` 结果为:1234 3. atol(): 将字符串转换为long类型的值。 例如: ```c++ char str[] = "1234567"; long num = atol(str); printf("%ld", num); ``` 结果为:1234567 4. strtod(): 类似于atof(),将字符串转换为double类型的值。 例如: ```c++ char str[] = "3.14"; double num = strtod(str, NULL); printf("%f", num); ``` 结果为:3.140000 5. strtol(): 将字符串转换为long类型的值,同时支持指定转换的基数(例如10进制、16进制等)和错误检查。 例如: ```c++ char str[] = "0110"; long num = strtol(str, NULL, 2); printf("%ld", num); ``` 结果为:6 6. strtoul(): 类似于strtol(),不过返回的是无符号的long类型。 例如: ```c++ char str[] = "0xA"; unsigned long num = strtoul(str, NULL, 16); printf("%lu", num); ``` 结果为:10 7. memset(): 将一段内存区域设置为指定的值。 例如: ```c++ char str[10]; memset(str, 'a', sizeof(str)); printf("%s", str); ``` 结果为:aaaaaaa 8. memcpy(): 将一段内存区域的内容复制到另一段内存区域。 例如: ```c++ char src[] = "hello"; char dst[10]; memcpy(dst, src, sizeof(src)); printf("%s", dst); ``` 结果为:hello 9. memmove(): 和memcpy()类似,但是保证在有重叠的情况下会正确工作。 例如: ```c++ char str[] = "hello"; memmove(str + 2, str, 3); printf("%s", str); ``` 结果为:hehlo 10. memcmp(): 比较两段内存区域的内容是否相等。 例如: ```c++ char str1[] = "hello"; char str2[] = "Hello"; int result = memcmp(str1, str2, 5); printf("%d", result); ``` 结果为:32(h和H的ASCII码差值) 11. memchr(): 在一段内存区域中搜索指定的字符,并返回指向该字符的指针。 例如: ```c++ char str[] = "hello"; char* ptr = (char*)memchr(str, 'l', 5); printf("%s", ptr); ``` 结果为:ll 12. strcpy(): 将一个字符串复制到另一个字符串。 例如: ```c++ char src[] = "hello"; char dst[10]; strcpy(dst, src); printf("%s", dst); ``` 结果为:hello 13. strncpy(): 类似于strcpy(),不过只会复制指定长度的字符。 例如: ```c++ char src[] = "hello"; char dst[10]; strncpy(dst, src, 3); dst[3] = '\0'; printf("%s", dst); ``` 结果为:hel 14. strcat(): 将一个字符串附加到另一个字符串的末尾。 例如: ```c++ char str1[] = "hello"; char str2[] = "world"; strcat(str1, str2); printf("%s", str1); ``` 结果为:helloworld 15. strncat(): 类似于strcat(),不过只会附加指定长度的字符。 例如: ```c++ char str1[] = "hello"; char str2[] = "world"; strncat(str1, str2, 3); printf("%s", str1); ``` 结果为:helloworld 16. strcmp(): 比较两个字符串是否相等。 例如: ```c++ char str1[] = "hello"; char str2[] = "world"; int result = strcmp(str1, str2); printf("%d", result); ``` 结果为:-15 17. strncmp(): 类似于strcmp(),不过只会比较指定长度的字符。 例如: ```c++ char str1[] = "hello"; char str2[] = "world"; int result = strncmp(str1, str2, 3); printf("%d", result); ``` 结果为:0 18. strchr(): 在一个字符串中搜索指定的字符,并返回指向该字符的指针。 例如: ```c++ char str[] = "hello"; char* ptr = strchr(str, 'l'); printf("%s", ptr); ``` 结果为:llo 19. strrchr(): 类似于strchr(),不过会从字符串的末尾开始搜索。 例如: ```c++ char str[] = "hello"; char* ptr = strrchr(str, 'l'); printf("%s", ptr); ``` 结果为:lo 20. strstr(): 在一个字符串中搜索指定的子字符串,并返回指向该子字符串的指针。 例如: ```c++ char str[] = "hello world"; char* ptr = strstr(str, "world"); printf("%s", ptr); ``` 结果为:world
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值