C中的memset()

时间:2020-02-23 14:32:04  来源:igfitidea点击:

C语言中的memset()函数用于设置具有特定值的内存块。

在本文中,我们将介绍如何在C程序中使用此功能。

C中memset()的语法

该函数需要一个存储位置,该存储位置应为void *指针。
然后,它将一个字节(字符)复制到存储位置所指向的前n个字节中。

由于它会更新内存位置,因此它还会返回一个指向该更新后的内存位置的指针,它也是一个" void *"指针。

因此,我们可以将其原型编写为:

void* memset(void* mem_loc, int c, size_t n);

其中" mem_loc"是相关的存储位置,而" c"是未签名的字符。
它设置mem_loc的前n个字节。

相关头文件

由于它处理字符,因此也处理字符串(char *),因此我们在<string.h>标头中获得此功能。

现在,我们将编写完整的导入和函数调用。

#include <string.h>

void* memset(void* mem_loc, int c, size_t n);

现在,让我们看一下有关如何使用此功能的示例。

在C中使用memset()函数

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

int main() {
  char a[] = {"Hello from theitroad"};

  printf("a = %s\n", a);
  
  printf("Filling the first 5 characters a with 'H' using memset\n");
  
  memset(a, 'H', 5 * sizeof(char));
  
  printf("After memset, a = %s\n", a);

  return 0;
}

上面的代码段用" H"填充了字符串" Hello from theitroad"的前5个字符。
现在让我们看一下输出:

a = Hello from theitroad
Filling the first 5 characters a with 'H' using memset
After memset, a = HHHHH from theitroad

如您所见,前5个位置确实充满了" H"。

现在再举一个例子,您想从偏移位置填充元素。

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

int main() {
  char a[] = {"Hello from theitroad"};

  printf("a = %s\n", a);
  
  printf("Filling the last 5 characters a with 'H' using memset\n");
  
  size_t a_len = strlen(a);
  
  //Using an offset of (a + a_len - 5), so that we can
  //fill the last 5 characters
  memset(a + (a_len - 5), 'H', 5 * sizeof(char));
  
  printf("After memset, a = %s\n", a);

  return 0;
}

输出

a = Hello from theitroad
Filling the last 5 characters a with 'H' using memset
After memset, a = Hello from JournHHHHH

这次,由于我们适当地指定了起始存储位置地址,因此最后五个字符用" H"填充。

memset()vs calloc()vs天真的迭代

很多时候,我们可以使用memset()将数组初始化为零。
通常," memset()"的性能比" calloc()"之类的类似方法要快得多。

下面的示例通过使用<time.h>头文件比较Linux计算机上的memset()calloc()的运行时间,说明了这一点。

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

void* init_with_memset(int* arr, size_t num_locations) {
  //Perform zero initialization with memset
  //on an integer array
  return memset(arr, 0, num_locations * sizeof(int)); 
}

void* init_with_calloc(int* arr, size_t num_locations) {
  arr = calloc(num_locations, sizeof(int));
  return arr;
}

void* init_with_iteration(int* arr, size_t num_locations) {
  //Naive unoptimized iteration using array indexing
  for (int i=0; i<num_locations; i++) {
      arr[i] = 0;
  }
  return arr;
}

int main() {
  //Set the array to -1 initially
  int arr[2560];
  for (int i=0; i<2560; i++)
      arr[i] = -1;

  clock_t start_time, end_time;
  double total_time;

  start_time = clock();
  //1000 locations
  init_with_memset(arr, 1000);
  end_time = clock();
  total_time  =  (double) (end_time - start_time);
  total_time =   total_time/CLOCKS_PER_SEC;
  printf("Time for memset() = %.6f seconds\n", total_time);
  
  start_time = clock();
  //1000 locations
  init_with_calloc(arr, 1000);
  end_time = clock();
  total_time  =  (double) (end_time - start_time);
  total_time =   total_time/CLOCKS_PER_SEC;
  printf("Time for calloc() = %.6f seconds\n", total_time);
  
  start_time = clock();
  //1000 locations
  init_with_iteration(arr, 1000);
  end_time = clock();
  total_time  =  (double) (end_time - start_time);
  total_time =   total_time/CLOCKS_PER_SEC;
  printf("Time for naive iteration = %.6f seconds\n", total_time);

  return 0;
}

输出

Time for memset() = 0.000002 seconds
Time for calloc() = 0.000005 seconds
Time for naive iteration = 0.000006 seconds

如您所见,memset()几乎是calloc()和天真的迭代速度的三倍,因为它是基于体系结构进行优化的,超出了C编译器!