谈一谈,c/c++中的memset()函数

1,400 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1 简介

memset()是计算机中C/C++语言初始化函数,在头文件#include<string.h>中定义。作用是将某一块内存中的内容全部设置为指定的值,这个函数通常为新申请的内存做初始化工作。其函数原型如下:

extern void *memset(void *buffer, int ch, int count)

其中:

  • buffer:为指向一片内存空间的指针(任意类型);
  • ch: 要被设置的值。该值以 int 形式传递;
  • count:被设置为该值的字节数。

memset()它是对较大的结构体或数组进行赋值初始化的一种最快方法。下面来对它的用法进行探讨。

2 用法

2.1 对char型指针进行赋值操作

char型指针的初始化过程中,使用memset()会非常方便,如下面程序,memset(str, 0, sizeof(str));可以很方便将str所指内存初始为0;并且memset()还能完成赋值操作,如memset(str, '$', 7);,将str所指内存的前7个字节赋值为$。但这只是在char型指针中能这样做,在其它类型指针中,就要小心。下面来看一下。

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

int main ()
{
    char str[50];

    memset(str, 0, sizeof(str));

    strcpy(str, "This is string.h library function");
    printf("%s\n", str);

    memset(str, '$', 7);
    printf("%s\n", str);

    return(0);
}

输出:

This is string.h library function
$$$$$$$ string.h library function

2.2 对int型指针进行赋值操作

采用memset()int型指针指向的内存块进行初始化时,一定要注意下面两点

  1. memset()函数按字节对内存块进行初始化,所以不能用它将int数组(内存块)初始化为0-1之外的其他值(除非该值高字节和低字节相同)。
  2. memset(void *s, int ch,size_t n);ch实际范围应该在[0255][0-255],因为该函数只能取ch的后八位赋值给你所输入的范围的每个字节,比如int a[5]赋值memset(a,-1,20)memset(a,511,20) 所赋值的结果是一样的都为-1(0xffffffff);因为-1的二进制码为(11111111 11111111 11111111 11111111)511的二进制码为(00000000 00000000 00000001 11111111)后八位都为(11111111),所以数组中每个字节,如a[0含四个字节都被赋值为(11111111),其结果为a[0](11111111 11111111 11111111 11111111),即a[0]=-1(0xffffffff),因此无论ch多大只有后八位二进制有效,而后八位二进制的范围为[0255][0-255]。而对字符数组操作时则取后八位赋值给字符数组,其八位值作为ASCII码

如下例子中的void test2(void)void test3(void)函数,用memset(a, 0, sizeof(a));memset(a, -1, sizeof(a));分别将a指向的内存初始化为全0和全1,输出结果中,采用十六进制输出。而void test1(void)中,memset(a, 1, sizeof(a));初始化后,其十六进制结果输出为0x1010101,因为1的二进制是(00000001),int有四个字节所以初始化结果应该为(00000001 00000001 00000001 00000001),转成十六进制后就是0x1010101。对于void test4(void)中,其初始化memset(a, 128, sizeof(a));后,十六进制结果输出为0x80808080128的二进制表示为10000000(0x80)int有四个字节所以初始化结果应该为(10000000 10000000 10000000 10000000),转成十六进制后就是0x80808080

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

void test1(void)
{
    int a[5];
	memset(a, 1, sizeof(a));

	for (int i = 0; i < 5; i++)
		printf("test1 a[%d]=%x\n", i, a[i]);

	printf("\n");

	return;
}

void test2(void)
{
	int a[5];
	memset(a, 0, sizeof(a));

	for (int i = 0; i < 5; i++)
		printf("test2 a[%d]=%x\n", i, a[i]);

	printf("\n");

	return;
}

void test3(void)
{
	int a[5];
	memset(a, -1, sizeof(a));

	for (int i = 0; i < 5; i++)
		printf("test3 a[%d]=%x\n", i, a[i]);
	printf("\n");

	return;
}

void test4(void)
{
	int a[5];
	memset(a, 128, sizeof(a));

	for (int i = 0; i < 5; i++)
		printf("test4 a[%d]=%x\n", i, a[i]);
	printf("\n");

	return;
}

int main()
{
	test1();
	test2();
	test3();
	test4();

	return(0);
}

输出:

test1 a[0]=1010101
test1 a[1]=1010101
test1 a[2]=1010101
test1 a[3]=1010101
test1 a[4]=1010101

test2 a[0]=0
test2 a[1]=0
test2 a[2]=0
test2 a[3]=0
test2 a[4]=0

test3 a[0]=ffffffff
test3 a[1]=ffffffff
test3 a[2]=ffffffff
test3 a[3]=ffffffff
test3 a[4]=ffffffff

test4 a[0]=80808080
test4 a[1]=80808080
test4 a[2]=80808080
test4 a[3]=80808080
test4 a[4]=80808080

2.3 对其它型指针进行赋值操作

对于其它类型的指针,采用memset()进行初始化,其注意事项和2.2是一致的。

3 总结

  • memset()它是对较大的结构体或数组进行赋值初始化的一种最快方法;
  • memset()函数按字节对内存块进行初始化,所以不能用它将int数组(内存块)初始化为0-1之外的其他值;
  • memset()char型指针进行赋值操作可以是任何ASCII码(没有int数组面临的问题)。