C#指针使用简析

开发 后端
C#指针在.net的时代指针已经被封装起来为什么还在使用,还能使用呢?本文将向你介绍C#指针的特点等等内容。

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

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

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

下面就C#指针来看其他指针的一些使用上的理解:

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

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

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

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

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

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

附C#指针的实现:

  1. public unsafe class Memory  
  2.     {  
  3. // Handle for the process heap.  
  4. // This handle is used in all calls to the  
  5. // HeapXXX APIs in the methods below.  
  6. static int ph = GetProcessHeap();  
  7. // Private instance constructor to prevent instantiation.  
  8. private Memory() { }  
  9. // Allocates a memory block of the given size.   
  10. //The allocated memory is  
  11. // automatically initialized to zero.  
  12. public static void* Alloc(int size)  
  13. {  
  14.     void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);  
  15.     if (result == nullthrow new OutOfMemoryException();  
  16.     return result;  
  17. }  
  18. // Copies count bytes from src to dst.   
  19. //The source and destination  
  20. // blocks are permitted to overlap.  
  21. public static void Copy(void* src, void* dst, int count)  
  22. {  
  23.     byte* ps = (byte*)src;  
  24.     byte* pd = (byte*)dst;  
  25.     if (ps > pd)  
  26.     {  
  27. for (; count != 0; count--) *pd++ = *ps++;  
  28.     }  
  29.     else if (ps < pd)  
  30.     {  
  31. for (ps += count, pd += count;   
  32. count != 0; count--) *--pd = *--ps;  
  33.     }  
  34. }  
  35. // Frees a memory block.  
  36. public static void Free(void* block)  
  37. {  
  38.     if (!HeapFree(ph, 0, block))   
  39. throw new InvalidOperationException();  
  40. }  
  41. // Re-allocates a memory block.   
  42. //If the reallocation request is for a  
  43. // larger size, the additional region of memory is automatically  
  44. // initialized to zero.  
  45. public static void* ReAlloc(void* block, int size)  
  46. {  
  47.     void* result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, block, size);  
  48.     if (result == nullthrow new OutOfMemoryException();  
  49.     return result;  
  50. }  
  51. // Returns the size of a memory block.  
  52. public static int SizeOf(void* block)  
  53. {  
  54.     int result = HeapSize(ph, 0, block);  
  55.     if (result == -1) throw new InvalidOperationException();  
  56.     return result;  
  57. }  
  58. // Heap API flags  
  59. const int HEAP_ZERO_MEMORY = 0x00000008;  
  60. // Heap API functions  
  61. [DllImport("kernel32")]  
  62. static extern int GetProcessHeap();  
  63. [DllImport("kernel32")]  
  64. static extern void* HeapAlloc(int hHeap, int flags, int size);  
  65. [DllImport("kernel32")]  
  66. static extern bool HeapFree(int hHeap, int flags, void* block);  
  67. [DllImport("kernel32")]  
  68. static extern void* HeapReAlloc(int hHeap, int flags,  
  69.    void* block, int size);  
  70. [DllImport("kernel32")]  
  71. static extern int HeapSize(int hHeap, int flags, void* block);  
  72.     } 

C#指针方面的内容就向你介绍到这里,希望对你了解学习C#指针有所帮助。

【编辑推荐】

  1. C#结构体构造函数的应用
  2. C#结构体定义的详解
  3. C#的结构体使用实例浅析
  4. C#结构体变量学习浅谈
  5. 解析C#结构体指针
责任编辑:仲衡 来源: 编程论坛
相关推荐

2009-09-03 17:10:57

2009-08-13 10:27:28

C#读取Excel数据

2009-08-12 10:07:51

C#运算符

2009-09-03 14:20:21

C#日期格式化

2009-09-03 10:52:41

C#递归树

2009-08-18 17:29:02

C#使用指针

2009-08-19 12:58:19

C#操作Word

2009-08-13 14:36:40

C#结构体构造函数

2009-08-12 16:38:35

C#读取XML节点

2009-08-20 16:02:15

C#正则表达式

2009-08-21 15:16:23

C#使用指针

2009-09-09 18:41:42

C# 加密散列算法

2009-08-20 09:58:06

C#操作文本文件

2010-01-20 14:25:56

函数调用

2010-01-25 10:10:42

C++函数参数

2010-01-18 15:53:27

C++析构函数

2011-07-12 14:04:58

2009-07-30 15:24:13

C#析构函数C#构造函数

2009-08-13 15:41:50

C#结构体指针

2009-09-02 10:49:46

C#调用析构方法
点赞
收藏

51CTO技术栈公众号