C#使用指针详细介绍

开发 后端
这里介绍要C#使用指针首先要对使用指针的代码用unsafe进行进行声明,声明和public声明一样,可以对整个类进行声明,也可以是类里面某个方法或者属性。

指针在C\C++里面可是一个好东西,但是到java,.net的时代指针已经被封装起来,对用户不可见,这点java做的非常的彻底。.net可能因为还存在一个托管C++,因此指针并没有完全废除,C#还是保留了指针的操作。

要C#使用指针首先要对使用指针的代码用unsafe进行进行声明,声明和public声明一样,可以对整个类进行声明,也可以是类里面某个方法或者属性。在代码里什么后,还需要修改工程项目的Build属性,让编译器支持指针的操作。

做好事前的工作就可以C#使用指针了。指针的使用方法和C++下使用没有太多差别。只要编译器不报错就没有太大问题。

下面是对指针的一些使用上的理解:

1.指针类型可以是实体变量(int,double)也可以是enum,同时也支持结构体变量struct。但不能是类。不过空指针可以指向类,只不过空指针不能进行任何操作,也只能把空指针作为传递对象来使用。

2.C#提供一个的关键字stackalloc用于申请堆栈内存。注意,这个申请内存分配的是栈内存,当函数执行完毕后,内存会被自动回收。不过我想用这个栈内存基本可以解决40%的问题,而且使用的时候不必担心内存泄漏问题。

3 .net好像不直接支持堆内存的申请(这个对.net来说很危险),不过我们可以通过调用win32 api 的方法进行申请。这样就可以解决剩下40%的问题。堆内存申请的方法在MSDN里面有相关的文档,具体实现代码见附1。

4.结构体是一个特殊的对象。他与类的定义就差一个关键字,使用方法也和类一样,可以定义属性,可以定义方法。但是在进行指针操作的时候双方就有很大的差别了。结构体可以通过sizeof()取得大小,大小与结构体里有多少实体变量有关,但是如果struck里定义了类的对象,或者指针,sizeof可能会编译不过(void* 的空指针例外,不过需要在结构体声明处加上unsafe)。

5.fixed关键字:目前了解的不多,不过有一个很实用的例子可以让C#使用指针能够和.net里的数组进行交互操作:

  1. byte[]buffer=newbyte[100];  
  2. fixed(byte*p=buffer)  
  3. {  
  4. P[0]=123;  
  5. ……  

其它

  1. publicunsafeclassMemory  
  2. {  
  3. //Handlefortheprocessheap.Thishandleisusedinallcallstothe  
  4. //HeapXXXAPIsinthemethodsbelow.  
  5. staticintph=GetProcessHeap();  
  6. //Privateinstanceconstructortopreventinstantiation.  
  7. privateMemory(){}  
  8. //Allocatesamemoryblockofthegivensize.Theallocatedmemoryis  
  9. //automaticallyinitializedtozero.  
  10. publicstaticvoid*Alloc(intsize)  
  11. {  
  12. void*result=HeapAlloc(ph,HEAP_ZERO_MEMORY,size);  
  13. if(result==null)thrownewOutOfMemoryException();  
  14. returnresult;  
  15. }  
  16. //Copiescountbytesfromsrctodst.Thesourceanddestination  
  17. //blocksarepermittedtooverlap.  
  18. publicstaticvoidCopy(void*src,void*dst,intcount)  
  19. {  
  20. byte*ps=(byte*)src;  
  21. byte*pd=(byte*)dst;  
  22. if(ps>pd)  
  23. {  
  24. for(;count!=0;count--)*pd++=*ps++;  
  25. }  
  26. elseif(ps<pd)  
  27. {  
  28. for(ps+=count,pd+=count;count!=0;count--)*--pd=*--ps;  
  29. }  
  30. }  
  31. //Freesamemoryblock.  
  32. publicstaticvoidFree(void*block)  
  33. {  
  34. if(!HeapFree(ph,0,block))thrownewInvalidOperationException();  
  35. }  
  36. //Re-allocatesamemoryblock.Ifthereallocationrequestisfora  
  37. //largersize,theadditionalregionofmemoryisautomatically  
  38. //initializedtozero.  
  39. publicstaticvoid*ReAlloc(void*block,intsize)  
  40. {  
  41. void*result=HeapReAlloc(ph,HEAP_ZERO_MEMORY,block,size);  
  42. if(result==null)thrownewOutOfMemoryException();  
  43. returnresult;  
  44. }  
  45. //Returnsthesizeofamemoryblock.  
  46. publicstaticintSizeOf(void*block)  
  47. {  
  48. intresult=HeapSize(ph,0,block);  
  49. if(result==-1)thrownewInvalidOperationException();  
  50. returnresult;  
  51. }  
  52. //HeapAPIflags  
  53. constintHEAP_ZERO_MEMORY=0x00000008;  
  54. //HeapAPIfunctions  
  55. [DllImport("kernel32")]  
  56. staticexternintGetProcessHeap();  
  57. [DllImport("kernel32")]  
  58. staticexternvoid*HeapAlloc(inthHeap,intflags,intsize);  
  59. [DllImport("kernel32")]  
  60. staticexternboolHeapFree(inthHeap,intflags,void*block);  
  61. [DllImport("kernel32")]  
  62. staticexternvoid*HeapReAlloc(inthHeap,intflags,  
  63. void*block,intsize);  
  64. [DllImport("kernel32")]  
  65. staticexternintHeapSize(inthHeap,intflags,void*block);  

【编辑推荐】

  1. 如何用C#和ADO.NET访问
  2. 浅析C# Switch语句
  3. C#验证输入方法详解
  4. 简单介绍C# 匿名方法
  5. C# FileSystemWatcher对象
责任编辑:佚名 来源: 腾讯科技
相关推荐

2011-07-20 16:43:34

C++

2009-08-03 17:12:40

C#指针操作

2009-08-10 16:30:56

C# BitmapDa

2009-08-12 15:34:40

C# DBNull

2009-08-18 17:37:57

C#固定指针

2011-07-15 01:20:58

C指针函数函数指针

2009-09-27 11:14:09

C#数组

2009-08-18 17:29:02

C#使用指针

2009-08-03 18:49:17

C#和Java

2009-08-26 17:31:59

C# const常量

2009-08-20 15:26:42

C#循环语句

2009-08-07 16:10:20

C#调用API

2009-08-24 18:21:23

C# ListView

2009-08-21 09:23:11

C# GDI+

2009-08-14 17:04:50

C#类型系统

2009-08-13 13:38:30

C#命名规范

2009-08-13 15:48:57

C#指针

2009-08-25 17:28:23

C#创建DataSet

2009-08-27 14:32:15

C#编写ActiveX

2009-08-06 14:59:36

C#编译器
点赞
收藏

51CTO技术栈公众号