深入学习C语言中memset()函数的用法

 更新时间:2015年08月26日 15:40:18   作者:蔡国武  
这篇文章主要介绍了深入学习C语言中memset()函数的用法,是C语言入门学习中的基础知识,需要的朋友可以参考下

头文件:

#include <string.h>

memset() 函数用来将指定内存的前n个字节设置为特定的值,其原型为:
  

 void * memset( void * ptr, int value, size_t num );

参数说明:
ptr 为要操作的内存的指针。
value 为要设置的值。你既可以向 value 传递 int 类型的值,也可以传递 char 类型的值,int 和 char 可以根据 ASCII 码相互转换。
num 为 ptr 的前 num 个字节,size_t 就是unsigned int。

【函数说明】memset() 会将 ptr 所指的内存区域的前 num 个字节的值都设置为 value,然后返回指向 ptr 的指针。

memset() 可以将一段内存空间全部设置为特定的值,所以经常用来初始化字符数组。例如:

char str[20];
memset(str, '\0', sizeof(str)-1);

【返回值】返回指向 ptr 的指针。

注意:参数 value 虽声明为 int,但必须是 unsigned char,所以范围在0 到255 之间。

范例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
 // 不可以声明为 char *str = "http://c.biancheng.net";
 char str[] = "http://c.biancheng.net";
 memset(str, '-', 7);
 puts(str);
 system("pause");
 return EXIT_SUCCESS;
}

执行结果:

-------c.biancheng.net

优化:尽量用memset将一个数组设置清零(带虚类除外),而不是通过for循环逐个置0
  
    下面这个例子,大家可以参考:3D游戏编程大师技巧。本文其实重点是memset,原因是在工作中,用的比较多。
 
    例如:要清空一个float f[10000],应该用memset(f,0,sizeof(float) * 10000);
    而不是: for(int i=0; i<10000; ++i) f[i] = 0;
    当然,还可以用内嵌汇编的形式:
   

 _asm
  {
  mov edi, f;  // edi指向数组地的目标内存的起始处
  mov ecx, 1000/4; // 循环次数或移动次数
  mov eax, 0;  // 每一次移动32位数,都置0
  rep stosd;  // 移动数据
  } 

 
    哈,这个准则有个前提,那就是带虚的类除外,原因是,memset将类清空,有可能将虚表也给置0了。
有可能是因为:类的创建分:栈上和堆上。
   如果在栈上,那么栈对象的虚函数调用可能会在静态时确定,从而绕过虚表。所以不会出错。
   但堆上就一定会出错,下面给出测试代码:

class CMemsetVirtualTest // 测试 带虚类,被memset为0后,虚表是否失效
{
public:
 CMemsetVirtualTest()
 {
  memset(this,0,sizeof(CMemsetVirtualTest));
 }
 
 virtual void NormalFun()
 {
  cout<<"test: NormalFun() 虚表指针有效"<<endl;
 }
 virtual ~CMemsetVirtualTest()
 {
 cout<<"test: ~CMemsetVirtualTest() 虚表指针有效"<<endl;
 }
}; 
void testFun1() // 测试:栈上建立的对象
{
 CMemsetVirtualTest Ctest;
 Ctest.NormalFun();
}
void testFun2() // 测试:堆上建立的对象
{
 CMemsetVirtualTest* Ptest = new CMemsetVirtualTest();
 Ptest->NormalFun(); // 到这里一定会暴掉
 delete Ptest;  // 如果屏蔽上句,到这里也一定会暴掉
}
 
int main()
{
 CMemsetVirtualTest Ctest;// 测试:栈上建立的对象
 Ctest.NormalFun();// 测试正常:
 
 CMemsetVirtualTest* Ptest = new CMemsetVirtualTest(); // 测试:堆上建立的对象
 Ptest->NormalFun(); // 到这里一定会暴掉
 delete Ptest;  // 如果屏蔽上句,到这里也一定会暴掉
}

 
   即:
   在C++中,涉及虚技术的类,他的对象内存区块中就不单纯是用户定义这个类时看上去的那些数据结构,编译器会在当中安插一些数据或代码,用来实现响应的虚技术.于是当你用memset函数时会把这些编译器安插的东西冲掉, 程序执行结果变得未知. 这时候如果拷贝对象C++会使用memberwise拷贝, 此时编译器既拷贝用户定义的数据结构,还会对支持虚技术的相关设施进行适当的修改.
   如果对象没有用到虚技术, 那么就可以使用memset,就跟正常情况一样,可以逐位拷贝.

相关文章

  • C语言的编程之美之内存函数

    C语言的编程之美之内存函数

    这篇文章主要介绍了C语言全部内存操作函数的实现详细讲解,作者用图文代码实例讲解的很清晰,有感兴趣的同学可以研究下
    2021-09-09
  • C++ Array容器的显示和隐式实例化详细介绍

    C++ Array容器的显示和隐式实例化详细介绍

    这篇文章主要介绍了C++中Array容器的隐式实例化和显式实例化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10
  • C语言实现socket简单通信实例

    C语言实现socket简单通信实例

    这篇文章主要介绍了C语言实现socket简单通信的方法,是学习C语言网络编程非常基础而又实用的实例,需要的朋友可以参考下
    2014-09-09
  • 详解C语言中双指针算法的使用

    详解C语言中双指针算法的使用

    双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。本文将通过示例带大家深入了解双指针算法的使用
    2022-08-08
  • 基于C++编写一个键盘提示音程序

    基于C++编写一个键盘提示音程序

    首先讲一下思路,这次制作的小黑子相当于键盘提示音,输入J,N,T,M,会发出“鸡你太美”的声音,连续按下JNTM则会发出“你干嘛啊,哎呦”的声音,感兴趣的可以了解一下
    2023-03-03
  • C语言实现哈夫曼树

    C语言实现哈夫曼树

    这篇文章主要为大家详细介绍了C语言实现哈夫曼树,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C++中使用function和bind绑定类成员函数的方法详解

    C++中使用function和bind绑定类成员函数的方法详解

    这篇文章主要介绍了C++中使用function和bind绑定类成员函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • C++超详细分析红黑树

    C++超详细分析红黑树

    这一篇我要跟大家介绍二叉搜索树中的另一颗树——红黑树,它主要是通过控制颜色来控制自身的平衡,但它的平衡没有AVL树的平衡那么严格
    2022-03-03
  • C语言输出旋转后数组中的最小数元素的算法原理与实例

    C语言输出旋转后数组中的最小数元素的算法原理与实例

    这篇文章主要介绍了C语言输出旋转后数组中的最小数元素的算法原理与实例,数组旋转就是把开头的几个指定的元素放到数组的末尾,需要的朋友可以参考下
    2016-03-03
  • C语言实现图的邻接矩阵存储操作

    C语言实现图的邻接矩阵存储操作

    这篇文章主要为大家详细介绍了C语言实现图的邻接矩阵存储操作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08

最新评论