函数内存操作整理

1. memcpy()

memcpy()函数用于将一段内存中的内容复制到另一段内存中。它需要三个参数:目标内存地址,源内存地址和要复制的字节数。该函数返回目标内存地址。示例代码:

void* memcpy(void* dest, const void* src, size_t n);

// 将字符串复制到数组 dest 中
#include <stdio.h>
#include <string.h>
 
int main ()
{
   const char src[50] = "http://www.runoob.com";
   char dest[50];
 
   memcpy(dest, src, strlen(src)+1);
   printf("dest = %s\n", dest);
   
   return(0);
}

输出结果:

dest = http://www.runoob.com

将 s 中第 11 个字符开始的 6个连续字符复制到 d 中:

#include <stdio.h>
#include<string.h>
 
int main()
 
{
  char *s="http://www.runoob.com";
  char d[20];
  memcpy(d, s+11, 6);// 从第 11 个字符(r)开始复制,连续复制 6 个字符(runoob)
  // 或者 memcpy(d, s+11*sizeof(char), 6*sizeof(char));
  d[6]='\0';
  printf("%s", d);
  return 0;
}

输出结果:

runoob

在该示例中,我们使用memcpy()函数将一个int数组的内容拷贝到一个char数组中。首先定义了一个包含10个元素的int数组arr1和一个长度为40个字节的char数组arr2。然后使用memcpy()函数将arr1数组的内容拷贝到arr2数组中,需要指定要拷贝的源地址、目标地址以及要拷贝的字节数。在本例中,我们使用sizeof()运算符获取arr1数组的字节数,以确保拷贝整个数组的内容。最后,使用for循环遍历arr2数组,并输出每个元素的值。

需要注意的是,使用memcpy()函数进行内存拷贝时,需要确保源地址和目标地址不会重叠,否则可能会导致意外的结果。另外,memcpy()函数拷贝的是一段连续的内存区域,而不会检查源地址和目标地址的类型和长度是否相同,因此需要确保拷贝的数据类型和长度是相同的。

2. memset()

memset()函数用于将一段内存中的所有字节都设置为指定的值。它需要三个参数:目标内存地址,要设置的值和要设置的字节数。该函数返回目标内存地址。示例代码:

void* memset(void* dest, int value, size_t n);

#include <stdio.h>
#include <string.h>

int main()
{
    // 定义一个包含10个元素的int数组
    int arr[10];
    
    // 使用memset()函数将arr数组的内容清零
    memset(arr, 0, sizeof(arr));
    
    // 输出arr数组的内容
    for(int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
    {
        printf("%d ", arr[i]);
    }
    
    return 0;
}

在该示例中,我们使用memset()函数将一个int数组的内容清零。首先定义了一个包含10个元素的int数组arr,然后使用memset()函数将arr数组的内容清零,需要指定要清零的地址、要清零的值(这里为0),以及要清零的字节数。在本例中,我们使用sizeof()运算符获取arr数组的字节数,以确保清零整个数组的内容。最后,使用for循环遍历arr数组,并输出每个元素的值。

需要注意的是,使用memset()函数进行内存清零时,需要注意清零的是一段连续的内存区域,而不是单个变量。因此,在清零数组时需要指定要清零的字节数,而在清零单个变量时可以直接将要清零的变量地址作为第一个参数传递给memset()函数。另外,memset()函数只能用于清零整数、字符、指针等基本数据类型的数组或变量,而不能用于清零复杂数据类型的结构体或类的对象。

3. memcmp()

memcmp()函数用于比较两段内存中的内容是否相等。它需要三个参数:要比较的两个内存地址和要比较的字节数。该函数返回一个整数值,如果相等则返回0,如果不相等则返回非0值。示例代码:

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

#include <stdio.h>
#include <string.h>

int main()
{
    // 定义两个相同大小的char数组
    char arr1[] = "hello";
    char arr2[] = "world";
    
    // 使用memcmp()函数比较arr1和arr2数组的内容
    int result = memcmp(arr1, arr2, sizeof(arr1));
    
    // 输出比较的结果
    if(result == 0)
    {
        printf("arr1和arr2相等\n");
    }
    else if(result < 0)
    {
        printf("arr1小于arr2\n");
    }
    else
    {
        printf("arr1大于arr2\n");
    }
    
    return 0;
}

在该示例中,我们使用memcmp()函数比较两个char数组的内容。首先定义了两个相同大小的char数组arr1和arr2,并将它们分别初始化为"hello"和"world"。然后使用memcmp()函数比较arr1和arr2数组的内容,需要指定要比较的源地址、目标地址以及要比较的字节数。在本例中,我们使用sizeof()运算符获取arr1数组的字节数,以确保比较整个数组的内容。最后,根据比较的结果输出相应的信息。

需要注意的是,使用memcmp()函数进行内存比较时,需要确保比较的是一段连续的内存区域,而且比较的字节数不能超过源地址和目标地址中较小的那个对应的字节数。另外,memcmp()函数返回一个整数值,表示两个内存区域的比较结果。如果源地址和目标地址的内容完全相同,返回值为0;如果源地址的内容小于目标地址的内容,返回值小于0;如果源地址的内容大于目标地址的内容,返回值大于0。

4. memmove()

memmove()函数用于将一段内存中的内容移动到另一段内存中。它需要三个参数:目标内存地址,源内存地址和要移动的字节数。该函数返回目标内存地址。和memcpy()不同的是,memmove()函数能够处理重叠的内存区域。示例代码:

void* memmove(void* dest, const void* src, size_t n);

#include <stdio.h>
#include <string.h>

int main()
{
    // 定义一个长度为20个字节的char数组
    char arr[20] = "Hello, world!";
    
    // 使用memmove()函数将arr数组的内容向右移动5个字节
    memmove(arr+5, arr, strlen(arr)+1);
    
    // 输出arr数组的内容
    printf("%s\n", arr);
    
    return 0;
}

在该示例中,我们使用memmove()函数将一个char数组的内容向右移动5个字节。首先定义了一个长度为20个字节的char数组arr,初始化为字符串"Hello, world!"。然后使用memmove()函数将arr数组的内容向右移动5个字节,需要指定要移动的源地址、目标地址以及要移动的字节数。在本例中,我们将源地址设置为arr数组的起始位置,目标地址设置为arr+5,即将arr数组的前5个字节移动到arr数组的第6个字节位置,使用strlen()函数获取arr数组的长度,并在最后加1是为了包含字符串结束符’\0’。最后,使用printf()函数输出移动后的arr数组内容。

需要注意的是,使用memmove()函数进行内存移动时,需要确保源地址和目标地址不会重叠,否则可能会导致意外的结果。另外,memmove()函数可以处理源地址和目标地址重叠的情况,因此比memcpy()函数更加安全,但是也会稍微降低一些性能。

5. malloc()

malloc()函数用于在堆内存中分配指定大小的内存空间,并返回该内存空间的首地址。它需要一个参数:要分配的内存空间的大小(以字节为单位)。示例代码:

void* malloc(size_t size);

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    
    printf("请输入需要分配的int变量个数:");
    scanf("%d", &n);
    
    // 使用malloc()函数分配n个int变量的内存空间
    int *arr = (int*)malloc(n * sizeof(int));
    
    // 判断内存分配是否成功
    if(arr == NULL)
    {
        printf("内存分配失败!\n");
        exit(1);
    }
    
    // 给每个变量赋值并输出
    for(int i = 0; i < n; i++)
    {
        arr[i] = i + 1;
        printf("%d ", arr[i]);
    }
    
    // 释放动态分配的内存空间
    free(arr);
    
    return 0;
}

在该示例中,我们使用malloc()函数动态分配了n个int变量的内存空间,并对每个变量赋值,并输出。首先使用scanf()函数从用户输入中获取需要分配的int变量个数n。然后使用malloc()函数分配n个int变量的内存空间,需要指定要分配的字节数(n * sizeof(int)),并将其强制类型转换为int类型的指针。在本例中,我们使用了if语句判断内存分配是否成功,如果返回值为NULL,则说明内存分配失败,此时应该使用exit()函数退出程序。接下来,使用for循环给每个变量赋值并输出。最后,使用free()函数释放动态分配的内存空间,以便其他程序或系统可以使用该内存空间。

需要注意的是,使用malloc()函数动态分配内存空间时,应该始终检查返回的指针是否为NULL,以确保内存分配成功。另外,动态分配的内存空间应该在使用完毕后及时释放,否则会造成内存泄漏。最后,对于动态分配的内存空间,应该始终使用free()函数进行释放,而不是直接将指针设为NULL。

6. calloc()

calloc()函数用于在堆内存中分配指定数量的连续内存空间,并初始化为0,并返回该内存空间的首地址。它需要两个参数:要分配的内存空间的数量和每个内存空间的大小(以字节为单位)。示例代码:

void* calloc(size_t count, size_t size);

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    
    printf("请输入要分配的int类型元素的个数:");
    scanf("%d", &n);
    
    // 使用calloc()函数动态分配n个int类型的元素
    int* arr = (int*)calloc(n, sizeof(int));
    
    // 检查内存是否成功分配
    if(arr == NULL)
    {
        printf("内存分配失败\n");
        return -1;
    }
    
    // 对arr数组进行赋值
    for(int i = 0; i < n; i++)
    {
        arr[i] = i + 1;
    }
    
    // 输出arr数组的内容
    for(int i = 0; i < n; i++)
    {
        printf("%d ", arr[i]);
    }
    
    // 释放动态分配的内存
    free(arr);
    
    return 0;
}

在该示例中,我们使用calloc()函数动态分配n个int类型的元素,并对其进行赋值和输出。首先通过scanf()函数从用户输入中读取n的值,然后使用calloc()函数动态分配n个int类型的元素,需要指定要分配的元素个数和每个元素的字节数。在本例中,我们使用sizeof(int)来获取每个int类型元素的字节数。如果内存分配成功,calloc()函数会返回一个指向分配内存首地址的指针,否则返回NULL。因此,在本例中我们需要检查返回的指针是否为NULL,以判断内存是否成功分配。接下来,使用for循环对arr数组进行赋值和输出。最后,使用free()函数释放动态分配的内存。

需要注意的是,使用calloc()函数动态分配内存时,需要确保分配的内存大小不会超出系统可用内存大小。另外,使用calloc()函数分配的内存块都会被初始化为0,而使用malloc()函数分配的内存块则不会。因此,在需要初始化内存块的情况下,推荐使用calloc()函数。

7. realloc()

realloc()函数用于重新分配已经分配的内存空间的大小,并返回该内存空间的首地址。它需要两个参数:已经分配的内存空间的首地址和要重新分配的内存空间的大小(以字节为单位)。示例代码:

void* realloc(void* ptr, size_t size);

#include <stdio.h>
#include <stdlib.h>

int main()
{
    // 定义一个指向int类型的指针
    int *arr = NULL;
    
    // 使用malloc()函数分配5个int类型的空间
    arr = (int*)malloc(5 * sizeof(int));
    
    // 输出arr数组的内容
    printf("Before realloc():\n");
    for(int i = 0; i < 5; i++)
    {
        printf("%d ", arr[i]);
    }
    
    // 使用realloc()函数重新分配10个int类型的空间
    arr = (int*)realloc(arr, 10 * sizeof(int));
    
    // 输出arr数组的内容
    printf("\nAfter realloc():\n");
    for(int i = 0; i < 10; i++)
    {
        printf("%d ", arr[i]);
    }
    
    // 释放arr指向的动态内存空间
    free(arr);
    
    return 0;
}

在该示例中,我们使用malloc()函数分配了5个int类型的内存空间,并将指向该空间的指针arr保存下来。然后使用realloc()函数重新分配了10个int类型的内存空间,需要指定要重新分配的内存地址、要重新分配的字节数,以及要重新分配的内存区域的大小。在本例中,我们将要重新分配的字节数设为10 * sizeof(int),以确保重新分配10个int类型的空间。注意,由于realloc()函数可能会改变指针arr的值,因此需要将realloc()函数的返回值重新赋给指针arr。

需要注意的是,使用realloc()函数进行动态内存分配时,需要注意以下几点:

如果realloc()函数分配内存失败,它会返回NULL,并且原先分配的内存空间不会被释放,因此需要检查realloc()函数的返回值是否为NULL。
在使用realloc()函数重新分配内存时,如果重新分配的空间比原来的空间大,realloc()函数会返回一个指向新内存空间的指针,并且原来的内存空间内容将被自动复制到新空间中。如果重新分配的空间比原来的空间小,realloc()函数也会返回一个指向新内存空间的指针,但是原来的内存空间内容将被截断,只保留新空间所能容纳的内容。
使用realloc()函数重新分配内存空间时,需要指定要重新分配的内存地址,并且原先分配的内存空间必须是由malloc()、calloc()、realloc()等函数分配的,否则可能会导致意外的结果。

8. free()

free()函数用于释放已经分配的内存空间,并将该内存空间标记为可重用状态。它需要一个参数:要释放的内存空间的首地址。示例代码:

void free(void* ptr);

9. strlen()

strlen()函数用于获取一个以null结尾的字符串的长度,不包括null字符。它需要一个参数:要获取长度的字符串的首地址。该函数返回字符串的长度。示例代码:

size_t strlen(const char* str);

#include <stdio.h>
#include <string.h>

int main()
{
    // 定义一个字符串
    char str[] = "Hello, world!";
    
    // 使用strlen()函数计算字符串的长度
    int len = strlen(str);
    
    // 输出字符串的长度
    printf("The length of the string is: %d\n", len);
    
    return 0;
}

在该示例中,我们使用strlen()函数计算一个字符串的长度。首先定义了一个字符串str,然后使用strlen()函数计算字符串的长度,该函数需要指定要计算长度的字符串地址,它会返回字符串中字符的数量,不包括字符串末尾的空字符’\0’。在本例中,我们将字符串的长度保存到一个变量len中,然后使用printf()函数输出字符串的长度。

需要注意的是,在使用strlen()函数计算字符串长度时,需要确保字符串以空字符’\0’结尾,否则可能会导致不正确的结果。如果一个字符串不以空字符’\0’结尾,strlen()函数可能会继续扫描内存,直到遇到一个空字符为止,这可能会导致访问非法内存区域并产生不可预测的行为。

10. strcpy()

strcpy()函数用于将一个以null结尾的字符串复制到另一个字符串中。它需要两个参数:目标字符串的首地址和源字符串的首地址。该函数返回目标字符串的首地址。示例代码:

char* strcpy(char* dest, const char* src);

#include <stdio.h>
#include <string.h>

int main()
{
    // 定义一个源字符串和目标字符串
    char src[] = "Hello, world!";
    char dest[20];
    
    // 使用strcpy()函数将src字符串拷贝到dest字符串中
    strcpy(dest, src);
    
    // 输出dest字符串的内容
    printf("%s", dest);
    
    return 0;
}

在该示例中,我们使用strcpy()函数将一个字符串拷贝到另一个字符串中。首先定义了一个源字符串src和一个目标字符串dest,其中目标字符串的长度要足够长,以便存储源字符串的内容。然后使用strcpy()函数将src字符串拷贝到dest字符串中,需要指定要拷贝的源地址和目标地址。在本例中,我们直接将源字符串和目标字符串的变量名作为参数传递给strcpy()函数。最后,使用printf()函数输出dest字符串的内容。

需要注意的是,使用strcpy()函数进行字符串拷贝时,需要确保目标字符串的长度足够长,以便存储源字符串的内容,否则可能会导致缓冲区溢出的问题。另外,如果源字符串的长度超过目标字符串的长度,则只会拷贝目标字符串长度的内容,并在目标字符串的结尾添加一个空字符(‘\0’)。因此,在使用strcpy()函数进行字符串拷贝时,需要注意目标字符串的长度和空间是否足够。

11. strcat()

strcat()函数用于将一个以null结尾的字符串追加到另一个字符串的末尾。它需要两个参数:目标字符串的首地址和源字符串的首地址。该函数返回目标字符串的首地址。示例代码:

char* strcat(char* dest, const char* src);

#include <stdio.h>
#include <string.h>

int main()
{
    // 定义两个字符串
    char str1[20] = "Hello";
    char str2[20] = " world!";
    
    // 使用strcat()函数将str2字符串拼接到str1字符串的末尾
    strcat(str1, str2);
    
    // 输出拼接后的结果
    printf("%s\n", str1);
    
    return 0;
}

在该示例中,我们使用strcat()函数将一个字符串拼接到另一个字符串的末尾。首先定义了两个字符串str1和str2,分别为"Hello"和" world!"。然后使用strcat()函数将str2字符串拼接到str1字符串的末尾,需要指定要拼接的目标字符串和源字符串。在本例中,我们将str2字符串拼接到了str1字符串的末尾。最后,使用printf()函数输出拼接后的结果。

需要注意的是,使用strcat()函数进行字符串拼接时,需要确保目标字符串的缓冲区足够大,以便容纳拼接后的结果。否则可能会导致缓冲区溢出,引发未定义的行为。另外,strcat()函数只能用于拼接字符串,而不能用于拼接字符或数字等其他类型的数据。如果需要将其他类型的数据转换为字符串后再进行拼接,可以使用sprintf()函数或stringstream类等工具。

12. strcmp()

strcmp()函数用于比较两个以null结尾的字符串的大小。它需要两个参数:要比较的两个字符串的首地址。该函数返回一个整数值,如果第一个字符串小于第二个字符串,则返回负数;如果第一个字符串大于第二个字符串,则返回正数;如果两个字符串相等,则返回0。示例代码:

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

#include <stdio.h>
#include <string.h>

int main()
{
    // 定义两个字符串
    char str1[] = "Hello";
    char str2[] = "World";
    
    // 使用strcmp()函数比较两个字符串的大小关系
    int result = strcmp(str1, str2);
    
    // 根据比较结果输出不同的消息
    if(result < 0)
    {
        printf("%s is less than %s\n", str1, str2);
    }
    else if(result == 0)
    {
        printf("%s is equal to %s\n", str1, str2);
    }
    else
    {
        printf("%s is greater than %s\n", str1, str2);
    }
    
    return 0;
}

在该示例中,我们使用strcmp()函数比较两个字符串的大小关系。首先定义了两个字符串str1和str2,然后使用strcmp()函数比较它们的大小关系,函数会返回一个整数值,表示str1和str2的大小关系。如果str1小于str2,则返回一个负整数;如果str1等于str2,则返回0;如果str1大于str2,则返回一个正整数。在本例中,我们将比较结果存储在一个变量result中,然后根据比较结果输出不同的消息。

需要注意的是,strcmp()函数比较的是两个字符串的内容,而不是它们的地址。因此,在比较字符串时需要确保两个字符串的内容都是以null结尾的。另外,strcmp()函数是区分大小写的,如果要进行不区分大小写的字符串比较,可以使用strcasecmp()函数。

13. strtok()

strtok()函数用于将一个以null结尾的字符串分割成若干个子字符串。它需要两个参数:要分割的字符串和分隔符(一个字符或字符串)。该函数返回第一个子字符串的首地址,以后每次调用都返回下一个子字符串的首地址。示例代码:

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

#include <stdio.h>
#include <string.h>

int main()
{
    char str[] = "Hello,World!Welcome to my program.";
    char *token;
    
    // 使用strtok()函数分割字符串
    token = strtok(str, " ,.!");  // 分隔符包括空格、逗号、句号和感叹号
    
    while(token != NULL)
    {
        printf("%s\n", token);
        token = strtok(NULL, " ,.!");
    }
    
    return 0;
}

在该示例中,我们使用strtok()函数将一个包含多个单词和标点符号的字符串分割成多个单词。首先定义了一个包含字符串的字符数组str和一个指向字符的指针变量token。然后使用strtok()函数将str字符串分割成多个单词,需要指定要分割的字符串以及分隔符,多个分隔符可以通过空格分隔。在本例中,我们使用空格、逗号、句号和感叹号作为分隔符。strtok()函数返回分割后的第一个单词,并将原始字符串中的分隔符替换为null字符。接着使用while循环遍历分割后的单词,并输出每个单词的值。在循环中,使用strtok(NULL, " ,.!")获取下一个分割后的单词,NULL参数表示继续使用上一次的字符串分割结果,而不是重新分割。

需要注意的是,使用strtok()函数进行字符串分割时,需要注意原始字符串中的内容会被修改,因此需要备份原始字符串或者使用拷贝。另外,strtok()函数是一个线程不安全的函数,如果需要在多线程环境中使用,请使用线程安全的strtok_r()函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值