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里的数组进行交互操作: 

byte[] buffer = new byte[100];  
fixed (byte* p = buffer)  
{  
    P[0] = 123;  
    ……  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

附C#指针的实现:

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

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

【编辑推荐】

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

2009-08-13 10:27:28

C#读取Excel数据

2009-09-03 17:10:57

2009-08-12 10:07:51

C#运算符

2009-09-03 10:52:41

C#递归树

2009-09-03 14:20:21

C#日期格式化

2009-08-12 16:38:35

C#读取XML节点

2009-08-13 14:36:40

C#结构体构造函数

2009-08-19 12:58:19

C#操作Word

2009-08-18 17:29:02

C#使用指针

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#操作文本文件

2024-12-23 09:09:54

2010-01-20 14:25:56

函数调用

2010-01-25 10:10:42

C++函数参数

2011-07-12 14:04:58

2010-01-18 15:53:27

C++析构函数

2009-09-02 10:49:46

C#调用析构方法

2009-07-30 15:24:13

C#析构函数C#构造函数
点赞
收藏

51CTO技术栈公众号