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)
void *(memset) (void *s,int c,size_t n)
{
const unsigned char uc = c;
unsigned char *su;
for(su = s;0 < n;++su,--n)
*su = uc;
return s;
}
第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页有解释(其实是我没看懂),这里给出测试:
#include <string.h>
#define MAXSIZE 100000
int main()
{
char arr[MAXSIZE];
for(int i=0;i<10000;i++)
{
memset(arr,'0',sizeof(arr));
// for(int j=0;j<MAXSIZE;j++)
// arr[0] = '0';
}
return 0;
}
程序里的注释部分与memset行分别使用,结果是使用memset的程序运行时间大约为0.1s,而用for循环的程序要3s多。
综上:memset()可以用在字符数组的初始化以及类似于memset(arr,0,n*sizeof(int));的情况,效率比手动赋值要高的多。
分享到:
相关推荐
memset()函数的另一种纯c语言实现方式
memset头文件 c++版
单片机下实现的部分经典C库函数,包括printf,memset等,可以用来学习printf源码实现方法,还包括了memset,memcpy,memcmp,strtok,strlen,sprintf,printf函数的C语言实现方法
memset用法。。。。。。。。。。。。。。
U-BOOT源码分析及移植,分析uboot的原理,程序执行流程,以及下那个硬的分析2)lib_arm/board.c: start_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。这里只简要列...
memset
在学习memset函数的时候,查了一些资料,转一个对memset()的用法的一些初浅的体会。
本篇文章是对memset函数的使用进行了详细的分析介绍,需要的朋友参考下
内容涵盖memset函数的定义、使用方法、注意事项、局限性、安全性、优化技巧以及社区支持等高级内容。 **适用人群:** 本教程适合所有对编程和C语言感兴趣的初学者,尤其是那些需要了解如何在C语言中使用memset函数的...
本文将深入探讨memset函数的原理、应用场景以及使用时需要注意的 事项,帮助读者更好地理解和使用这一强大的工具。memset函数的工作原理相对简单:它将从s指向的内存地址开始,连续地设置n个字节的内容为c。这里的c...
为了提高效率,memset函数通常会利用硬件特性,如SIMD(单指令多数据)指令集,来加速内存的填充过程。这种直接操作内存的方式避免了循环逐个设置字节的繁琐过程,使得大量内存的初始化变得快速而简单。 在应用方面...
Linux下替换memset为自己写的函数,但是用jmp绝对跳转时会遇到段错误的问题
memset
ntdll.dll中memset为一段代码,它的功能是对堆栈中的一段进行清零,在调用时需要输入3个参数,分别是需清零堆栈段的首地址,清零堆栈段大小,清零堆栈段填充的内容
优化linux系统memcpy,及memset,这两个命令占比系统非常高,现用汇编来优化
本文详细介绍了Memset、Memcpy、Strcpy 的作用及三者的区别,函数原型及使用技巧等。
C语言memset用法详解
C语言memset函数使用方法详解 一。函数原形 void * memset(void*s, int ch,size_t n) 二。函数作用 将以s内存地址为首的连续n个字节的内容置成ch,一般用来对大量结构体和数组进行清零 三。常见错误 1.搞反...
可以在系统下修改内存时序,ddr3没试过