memset()实现及细节
memset是计算机中C/C++语言函数。将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。
头文件:<memory.h>或<string.h>
void *memset(void *s, int ch, size_t n);
函数解释:将s中前n个字节替换为ch并返回s;
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
一维数组的动态分配,初始化和撤销都好说,几乎每一本C++教材都会做出详细的说明。具体如下:
动态分配(例如分配10个单元的): int *array=new int [10];
初始化:memset(array,0,sizeof(array)); (也可以利用一个for循环对其赋值初始化)
撤销:delete [] array;
下面来说二维数组的。
二维数组(n行m列)利用new来进行动态分配实际上相当于对n个m元数组进行动态分配,只不过我们不能一味的按照动态分配一维数组的方法来这项操作。MSVC目前还没有这般的人性化,具体应该这样做:
int **array;
array=new int *[10];
for(int i=0;i<10;i++)
array[i]=new int [5];
上面的操作完成了一个10行5列的二维数组array[10][5]的动态分配,可以看到我们先动态分配了一个10单元的数组的指针的指针的首地址给**array,然后再对其每个首地址进行遍历,同时完成一个5单元的数组的动态分分配,并把首地址给*array[i],从而最终完成了二维数组array[10][5]的动态分配。我们可以依此类推得到三维以至多维的数组的动态分配方法。
二维数组的初始化:如果把一维数组初始化办法照搬过来就会发现对于动态分配的二维数组并不适用。这就要理解到memset这个函数三个参数的含义。MSDN对memset的描述如下:
memset
Sets buffers to a specified character.
void*memset(void*dest,intc,size_tcount);
可见memset只能作用于一个一维数组void*dest,因此最好的办法就是和二维数组的动态分配结合起来,new一个,memset一个。具体写法如下:
int **array;
array=new int *[10];
for(int i=0;i<10;i++)
{
array[i]=new int [5];
memset(array[i],0,5*sizeof(int));
}
编译平台:
Microsoft Visual C++ 6.0
也不一定就是把内容全部设置为ch指定的ASCII值,而且该处的ch可为int或者其他类型,并不一定要是char类型。例如下面这样:
int array[5] = {1,4,3,5,2};
for(int i = 0; i < 5; i++)
cout<<array[i]<<" ";
cout<<endl;
memset(array,0,5*sizeof(int));
for(int k = 0; k < 5; k++)
cout<<array[k]<<" ";
cout<<endl;
输出的结果就是:
1 4 3 5 2
0 0 0 0 0
后面的表大小的参数是以字节为单位,所以,对于int或其他的就并不是都乘默认的1(字符型)了。而且不同的机器上int的大小也可能不同,所以最好用sizeof()。
要注意的是,memset是对字节进行操作,所以上述程序如果改为
int array[5] = {1,4,3,5,2};
for(int i = 0; i < 5; i++)
cout<<array[i]<<" ";
cout<<endl;
memset(array,1,5*sizeof(int));// 注意 这里与上面的程序不同
for(int k = 0; k < 5; k++)
cout<<array[k]<<" ";
cout<<endl;
输出的结果就是:
1 4 3 5 2
16843009 16843009 16843009 16843009 16843009
为什么呢?
因为memset是以字节为单位就是对array指向的内存的5个字节进行赋值,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4字节,合一起就是00000001000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了。
所以用memset对非字符型数组赋初值是不可取的!
例如有一个结构体Some x,可以这样清零:
memset( &x, 0, sizeof(Some) );
如果是一个结构体的数组Some x[10],可以这样:
memset( x, 0, sizeof(Some)*10 );
memset()实现及细节的更多相关文章
- memset 在c++中使用细节注意
C语言,在利用struct进行数据封装时,经常会使用memset(this,0,sizeof(*this))来初始化.而C++中,有时候也会用到struct,在利用memset进行初始化时,非常容易踩 ...
- 字符串数组初始化0 与memset 0 效率的分析
转自:http://www.xuebuyuan.com/1722207.html 结合http://blog.sina.com.cn/s/blog_59d470310100gov8.html来看. 最 ...
- zoj 3745 Salary Increasing(坑爹的细节题!)
题目 注意题目中的,引用绝望的乐园中的进一步解释如下: 这是一道浙大月赛的题,一如既往的坑爹,好好一道水题,被搞成一道坑题!!! //注意:r(i) < l(i+1) !细节啊细节! #incl ...
- 关于fputs和fgets的几个细节
C语言中两个标准IO fputs和fgets都是针对行来进行数据的读取的!这里关于这两个IO函数我有几个小细节想在这里和大家分享一下,希望能够对大家产生帮助! 首先贴上这两个函数的函数声明,下面以这两 ...
- sizeof strlen strncpy用法总结 结构体实际所占内存大小 以及memset用法
sizeof测类型(数组名除外) strlen测实际长度 strncpy返回指针类型 #include <stdio.h> #include <stdlib.h> #inclu ...
- Linux 套接字编程中要注意的细节
隐患 1.忽略返回状态 第一个隐患很明显,但它是开发新手最容易犯的一个错误.如果您忽略函数的返回状态,当它们失败或部分成功的时候,您也许会迷失.反过来,这可能传播错误,使定位问题的源头变得困难. 捕获 ...
- HDU 2612 -Find a way (注重细节BFS)
主题链接:Find a Way 题目不难,前几天做,当时准备写双向BFS的,后来处理细节上出了点问题,赶上点事搁置了.今天晚上重写的,没用双向,用了两次BFS搜索,和双向BFS 道理差点儿相同.仅仅是 ...
- 细节MARK
在刷vijos1046的时候遇到了一些细节,MARK一下 1.哲学之前有告诫我说,输出long long的数的时候,最好用cout,不然容易出现编译器的问题,今天算是领教了 2.对于数组赋值问题 me ...
- socket网络编程快速上手(二)——细节问题(5)(完结篇)
6.Connect的使用方式 前面提到,connect发生EINTR错误时,是不能重新启动的.那怎么办呢,是关闭套接字还是直接退出进程呢?如果EINTR前,三次握手已经发起,我们当然希望链路就此已经建 ...
随机推荐
- 怎样用delphi关闭并重新启动 explorer.exe进程
uses Tlhelp32; function KillTask(ExeFileName:string):integer; const PROCESS_TERMINATE = $0001; var C ...
- ExtJS4之Ext.MessageBox的各种用法
1. Ext.Msg.alert(String title,String msg)[Ext.MsssageBox.alert(Sting title,Sting msg,fn)]与javascript ...
- 文件相关操作工具类——FileUtils.java
文件相关操作的工具类,创建文件.删除文件.删除目录.复制.移动文件.获取文件路径.获取目录下文件个数等,满足大多数系统需求. 源码如下:(点击下载 FileUtils.java) import jav ...
- 如何修改linux时间? 校正linux系统的时间
第一步:通过xshell远程连接到linux系统 第二步:输入 tzselect 第三步:选择所在的州,中国人请选择 5 ,亚洲 第四步:选择你所在的国家,中国人请选择9,中国 第五步:选择一个时区, ...
- js收藏
//设为主页function SetHome(obj, vrl) { try { obj.style.behavior = 'url(#default#homepage)'; obj.setHomeP ...
- 《OD大数据实战》HBase整合MapReduce和Hive
一.HBase整合MapReduce环境搭建 1. 搭建步骤1)在etc/hadoop目录中创建hbase-site.xml的软连接.在真正的集群环境中的时候,hadoop运行mapreduce会通过 ...
- oracle数据导入的常用命令
oracle 中数据库完全导入导出:cmd命令行模式 oracle数据库cmdfile数据库服务器constraints Oracle数据导入导出imp/exp就相当于oracle数据还原与备份.ex ...
- 如何使页面滚动条移动到指定元素element的位置处?
如何使页面滚动条移动到指定元素element的位置处? 在用selenium做测试时,会遇到需要操作的元素不在当前可视页面中的情况,如果是手工测试,自然很简单,手动拖拽滚动条到目标元素处即可. 那么, ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化
上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...
- design pattern及其使用
什么是设计模式? design pattern是一个通用的,可以被重用的关于一个常见的问题的解决方案. 为什么要用设计模式? 引入设计模式的理论基础非常简单.我们每天都会碰到问题.我们可能碰到决定使用 ...