memset

综述

首先,memset是一个比较*疼的东西,主要原因是它当初被设计出来主要是用来为字符串(比如char型数组)赋值的,但是当大家把它拿来给其他类型(比如int,double等)赋值的话,就该*疼了——

头文件与函数原型

之所以说memset用来处理字符串,可以行它的头文件略见一斑

string.h

这显然是来处理字符串的啊。

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

由原型可以看出:指针p为所操作的内存空间的首地址,c为每个字节所赋的值,n为所操作内存空间的字节长度,也就是内存被赋值为c的字节数。

举例及注意事项

下面问题来了,memset究竟要注意什么?

举个例子:

char a[10];
memset(a, '\n', 10);
这个例子说明了将一个10个字节的char型数组全部赋值为10个'\n',这当然可以,因为memset本来就是处理字符或字符串的。


问题是如果处理其他类型呢?

再举个例子:

int a[10];
memset(a, 1, 10);

结果是什么呢?是将10个int型的数组a全部赋值为整数1吗?显然不是的。

我们不妨从底层来看:一个int有4个字节,也就是说数组a其实是一个连续40个字节的存储空间。而memset(a, 1, 10)代表将10个字节赋值为1,也就是说a[0] = a[1] = 0x01010101,a[2] = 0x01010000,a[3] = a[4] = ... = a[9] = 0。

所以,赋值显然是失败的。失败的根源就是memset本来就是用来处理字符,按照字节来操作的,所以对其他类型的数据操作一定要慎重!


不过初始化(赋0值)int型数组倒是可以的:

int a[10];
memset(a, 1, 10*sizeof(int));

号外

对赋值的理解:

<span style="font-size:18px;">char c = 1;</span>

对于上面的代码,我们可以这样理解——

(1)从实际内存操作上看,上面的代码表示对c代表的字节赋1;

(2)从逻辑内容上看,上面的代码表示将c赋值为ASCII值1所代表的字符。


int m = 7;
int n = 8;
int i;

int **a;	//用malloc申请建立二维数组

a = (int **) malloc(m * sizeof(int *));

for(i=0; i<m; ++i)
    a[i] = (int *) malloc(n * sizeof(int));


memset(a, 0, sizeof(int) * m * n);	//wrong!!!


此时对二维数组初始化赋值为0是不对的,因为用这种方式申请出来的二维数组不是连续的。(准确的说这是 存放有指向一维int型数组的指针的一维int*型数组)


但是

int a[7][8];
memset(a, 0, 7*8*sizeof(int));
对这种定义的二维数组是可以的。因为这种申请方式保证了数组内存地址是连续的。

号外(临时补充内容):

<span style="font-size:18px;">char c = 1;</span>

对于上面的代码,我们可以这样理解——

(1)从实际内存操作上看,上面的代码表示对c代表的字节赋1;

(2)从逻辑内容上看,上面的代码表示将c赋值为ASCII值1所代表的字符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值