目录

一、memset函数

二、使用memset对char数组赋值

1、清零操作

2、赋为非0值操作

三、使用memset对int数组赋值

1、清零操作

2、赋为非0值操作

分析int数组赋非零值的情况

如何正确给int数组赋非0值

四、总结


一、memset函数

void *memset(void *s, int ch, size_t n);

函数解释:将s中当前位置后面的n个字节用 ch 替换并返回 s

参数:s,指针,要赋值的内存的起始地址。

ch,用于设置给内存块的值。

n,指定设置为ch值的字节数

作用:在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。

由函数解释可以知道,memset函数是对地址为s开始的n个字节的内存块进行赋值,而且是将这个n个字节的每个字节赋值为整数ch。这一点要注意,使用memset函数对内存块赋值是以字节为单位来赋值

 

二、使用memset对char数组赋值

1、清零操作

使用memset函数对char类型的数组进行清零操作,该示例直接以代码展示:

#include <stdio.h>
#include <memory.h>

int main(int argc, char* argv[]){
	int i;
	char ArrCh[10] = {0};
	
	memset(ArrCh, 0, sizeof(ArrCh));
	
	printf("char type, assign zero value:\n");
	for(i=0; i<sizeof(ArrCh); i++)
	{
		printf("0x%x, ", ArrCh[i]);
	}
	printf("\n");

	return 0;	
}

运行结果:

 

2、赋为非0值操作

使用memset函数对char类型的数组赋为非0值操作,该示例直接以代码展示:

#include <stdio.h>
#include <memory.h>

int main(int argc, char* argv[]){
	int i;
	char ArrCh[10] = {0};
	
	memset(ArrCh, 0x4, sizeof(ArrCh));		//赋值为0x4 
	
	printf("char type, assign non zero value:\n");
	for(i=0; i<sizeof(ArrCh); i++)
	{
		printf("0x%x, ", ArrCh[i]);
	}
	printf("\n");

	return 0;	
}

运行结果:

 

三、使用memset对int数组赋值

1、清零操作

使用memset函数对int类型的数组进行清零操作,该示例直接以代码展示:

#include <stdio.h>
#include <memory.h>

int main(int argc, char* argv[]){
	int i;
	int ArrInt[10] = {0};
	
	memset(ArrInt, 0, sizeof(ArrInt));
	
	//打印数组大小、元素类型大小、数组元素个数 
	printf("sizeof(ArrInt):%d, sizeof(int):%d, element counts of ArrInt:%d\n", 
			sizeof(ArrInt), sizeof(int), sizeof(ArrInt)/sizeof(int));		
	printf("int type, assign zero value:\n");
	for(i=0; i<sizeof(ArrInt)/sizeof(int); i++)
	{
		printf("0x%x, ", ArrInt[i]);
	}
	printf("\n");

	return 0;	
}

运行结果:

可见,使用memset函数对int类型数组进行清零操作,可以达到我们想要的效果。另外,同样可以使用memset函数对其它基本数据类型或结构体变量进行清零操作,达到快速清零一块内存的效果。

 

2、赋为非0值操作

使用memset函数对int类型的数组赋为非0值操作,这个场景是我们本文讲解的重点,因为其中存在易错点,我们先以示例代码来看效果,然后讲解易错点。

#include <stdio.h>
#include <memory.h>

int main(int argc, char* argv[]){
	int i;
	int ArrInt[10] = {0};
	
	memset(ArrInt, 0x4, sizeof(ArrInt));		//赋值为0x4 
	
	//打印数组大小、元素类型大小、数组元素个数 
	printf("sizeof(ArrInt):%d, sizeof(int):%d, element counts of ArrInt:%d\n", 
			sizeof(ArrInt), sizeof(int), sizeof(ArrInt)/sizeof(int));		
	printf("int type, assign non zero value:\n");
	for(i=0; i<sizeof(ArrInt)/sizeof(int); i++)
	{
		printf("0x%x, ", ArrInt[i]);
	}
	printf("\n");

	return 0;	
}

运行效果:

 

分析int数组赋非零值的情况

该示例本意是想对int类型数组的每个元素赋值为0x4,但从运行效果来看,int类型数据的每个元素的值却变为0x4040404,与我们预期的不一致。

为什么使用memset函数对char类型数组进行赋值(0值或者非0值)都正确,对int类型数组赋0值正确,而赋为非0值就与我们预期不同?发生这种现象的原因是什么?

这个问题的原因要回归到memset函数定义的理解上,从本文开头的memset函数的讲解就提到了注意事项:使用memset函数对内存块赋值是以字节为单位来赋值。所以使用memset函数对char类型数组进行赋值(0值或者非0值)都正确,因为char类型数组的元素大小都是1个字节,刚好与memset函数以字节为单位进行赋值一致。而int类型数组,我们示例代码int类型大小是4个字节,即int类型数组每个元素都是以4个字节为一个单位,“对int类型数组赋0值正确”,这个很好理解,因为将整个内存的每个字节都赋为0值,那么无论这个内存是存放什么数据类型的内存,即无论是以多少个字节作为一个单位,该单位打印出来的值都是0。

为何int类型数组赋为非0值,每个元素打印出来的值与我们预期不同?因为ArrInt数组的元素是int类型,大小是4个字节,那么每个元素都是4个字节,又由于memse函数是对内存块的每个字节赋值,所以是示例代码中,ArrInt数组的所占内存每个字节都是值0x4,所以ArrInt数组的一个int元素是4个字节且每个字节值为0x4,表示出来就是0x4040404(由于每个字节的值相同,表示该值可以不考虑大小端字节序),与打印出来的是一致的。

另外,我们可以改一下代码,将ArrInt数组以字节大小打印出来,验证我们的分析:

#include <stdio.h>
#include <memory.h>

int main(int argc, char* argv[]){
	int i;
	int ArrInt[10] = {0};
	
	memset(ArrInt, 0x4, sizeof(ArrInt));		//赋值为0x4 
	
	//打印数组大小、元素类型大小、数组元素个数 
	printf("sizeof(ArrInt):%d, sizeof(int):%d, element counts of ArrInt:%d\n", 
			sizeof(ArrInt), sizeof(int), sizeof(ArrInt)/sizeof(int));		
	printf("int type, assign non zero value, print as char unit:\n");
	char* pCh = (char*)ArrInt;	//转换为char指针 
	for(i=0; i<sizeof(ArrInt); i++)
	{
		printf("0x%x, ", pCh[i]);
	}
	printf("\n");

	return 0;	
}

 

运行效果:

可知,将ArrInt数组转换为char数组,char数组的每个元素都是0x4,说明这个内存块使用memset函数进行赋值,是以字节为单位进行的。

 

如何正确给int数组赋非0值

既然不能使用memset函数对int类型数组的每个元素赋非0值,那么如何解决int类型数组的元素赋非0值问题?直接的方法是使用循环,依次对每个元素赋值,示例代码如下。

#include <stdio.h>
#include <memory.h>

int main(int argc, char* argv[]){
	int i;
	int ArrInt[10] = {0};

	for(i=0; i<sizeof(ArrInt)/sizeof(int); i++)	//使用for循环对每个元素赋值 
	{
		ArrInt[i] = 0x4;
	}

	//打印数组大小、元素类型大小、数组元素个数 
	printf("sizeof(ArrInt):%d, sizeof(int):%d, element counts of ArrInt:%d\n", 
			sizeof(ArrInt), sizeof(int), sizeof(ArrInt)/sizeof(int));		

	for(i=0; i<sizeof(ArrInt)/sizeof(int); i++)
	{
		printf("0x%x, ", ArrInt[i]);
	}
	printf("\n");

	return 0;	
}

运行效果:

 

四、总结

1、可以使用memset函数对char类型数组的元素进行赋值(0值或非0值)。

2、可以使用memset函数对非char类型数组的元素进行赋0值,但不能使用memset函数直接对非char类型数组的元素赋非0值。这里的非char类型数组,是指数据类型大小不是1个字节的,比如short、int、long、占用字节数大于1个字节的结构体等。

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐