memset()函数源代码与fill()函数

一memset()函数:

 

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

 

 

作用:将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作。
不知道有没有像我一样把memset当作万能的初始化工具,例如:

int arr[n];  
memset(arr,1,n*sizeof(int));  
这样得到的arr数组一定不是全0,而是16843009,下面解释原因。
首先,变量类型的本质只是标志从某一内存地址开始读取的位数,强制转换就是改变读取位数的大小。

下面来看memset的实现:

 

 

void *(memset)(void *s, int c, size_t 4n)  
{  
const unsigned char uc = c;  
unsigned char *su;  
for (su = s; 0 < 4n; ++su, --4n)  
   *su = uc;  
return s;  
}  

 

 

  1.const unsigned char uc = c; 把int类型的c转换成unsigned char类型,意味着截去c的高24位,只保留低8位。

 

 

  2. 第4行把s当作unsigned char*类型,也就是说su中的每一个元素按8位计算。一直执行4*n次。因为传入函数的就是4*n,可以参考如下代码;

  

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
 
#define N 5
 
void * my_memset(void *dst, int val, size_t count)
{
        //把val传给*dst时两个变量类型要相同,需要用到强制类型转换
         
    assert(dst);                    //这里需要检验dst的有效性
    char* ret = (char*)dst;         
    while (count--)                
    {
        *ret++ = (char)val;
    }
    return dst;
}
int main()
{
    int arr[N];
    int i ;
    my_memset(arr,0,N*sizeof(int));
    for (i = 0; i < N; i++)
    {
        printf("%d\n", arr[i]);
    }
    system("pause");
    return 0;
}count)
{
        //把val传给*dst时两个变量类型要相同,需要用到强制类型转换
         
    assert(dst);                    //这里需要检验dst的有效性
    char* ret = (char*)dst;         
    while (count--)                
    {
        *ret++ = (char)val;
    }
    return dst;
}
int main()
{
    int arr[N];
    int i ;
    my_memset(arr,0,N*sizeof(int));
    for (i = 0; i < N; i++)
    {
        printf("%d\n", arr[i]);
    }
    system("pause");
    return 0;
}


现在来看看文章开头的那个代码会做什么。
c的二进制 : 00000000000000000000000000000001(32位)
1、c转换为unsigned char 后:00000001(8位)
2、将指针su(unsigned char类型)的每一元素(8位)赋值为00000001,循环4n次。
3、memset()结束后,arr的每个元素按照int类型读取,读出来的就是1000000010000000100000001,十进制就是16843009。

 

不过如果是memset(arr,0,n*sizeof(int));的话可以使用,因为32位都是0。

 

二.fill()函数:

  fill()函数也可以用来初始化,填充数据,而且局限性更小,具体解析见:点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值