目录
一、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个字节的结构体等。