zoukankan      html  css  js  c++  java
  • c语言memset源码

    c语言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的实现:(代码来自《C标准库》P398)

    1 void *(memset) (void *s,int c,size_t n)
    2 {
    3     const unsigned char uc = c;
    4     unsigned char *su;
    5     for(su = s;0 < n;++su,--n)
    6         *su = uc;
    7     return s;
    8 }

    第3行把int类型的c转换成unsigned char类型,意味着截去c的高24位,只保留低8位。第4行把s当作unsigned char*类型,也就是说su中的每一个元素按8位计算。
    现在来看看文章开头的那个代码会做什么。
    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

    三、效率分析

    再来说memset()的效率问题。使用memset函数与将上面的函数代码写在自己的程序里是不一样的,C标准库中的memset对Cache的利用做了优化,具体的在《C专家编程》151页有解释(其实是我没看懂),这里给出测试:

     1 #include <string.h>
     2 #define MAXSIZE 100000
     3 
     4 int main()
     5 {
     6     char arr[MAXSIZE];
     7     for(int i=0;i<10000;i++)
     8     {
     9         memset(arr,'0',sizeof(arr));
    10 //        for(int j=0;j<MAXSIZE;j++)
    11 //            arr[0] = '0';
    12     }
    13     return 0;
    14 }

    程序里的注释部分与memset行分别使用,结果是使用memset的程序运行时间大约为0.1s,而用for循环的程序要3s多。
    综上:memset()可以用在字符数组的初始化以及类似于memset(arr,0,n*sizeof(int));的情况,效率比手动赋值要高的多。

    参考:http://blog.csdn.net/hackbuteer1/article/details/7343189#

  • 相关阅读:
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
    UVA 11100 The Trip, 2007 (贪心)
    JXNU暑期选拔赛
    计蒜客---N的-2进制表示
    计蒜客---线段的总长
    计蒜客---最大质因数
    JustOj 2009: P1016 (dp)
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7259923.html
Copyright © 2011-2022 走看看