之前很少听说指针,也不知道是做什么的。今天看了下书,正好见到了指针,就我现在的理解来谈一谈。
1.什么是指针。
指针就是栈里面指向值存储的位置,也就值地址。
2.为什么要使用指正?
在调用windows api方法(windows api是什么,我前面的博客有写到一些操作windows的一些代码,如:调节音量,亮度等等,都是调用windows api)和c++语言编译的dll时,可能需要将指针作为参数传递。在C#中使用指针可以提高程序的性能。
3.怎么创建指针
指针在c# .net中是默认不安全代码,创建指针需要将程序设置为允许运行非安全代码,指针的关键字是unsafe。而且指针只能声明值类型 uint,int,byte,struct等。声明成功后的指针为非托管类型,也就是垃圾回收器不能处理他们。
4.为什么指针不能声明引用类型?
因为引用类型的地址,会由于垃圾回收期的回收和压缩经常变化,所以指针所指向的地址可能不是最初的引用类型的值。
5.类成员的指针
4上面说了,引用类型无法声明指针,但是有很多情况下,需要把类里面的值类型的成员声明成指针。
class myclass
{
public long x;
public long y;
}
var myobj=new myclass();
long* pl=&(myobj.x);
//这种写法是会报错的,因为指针声明了引用类型的成员
在这种情况下要如何实现呢?上面也说了,不能声明引用类型的原因是因为引用类型的地址是经常变化的,那我们只需要把他的地址固定就可以了
var myobj=new mycalss();
fixed(long* pl=&(myobj.x))
{
XXXX
}
使用fixed关键字,在fixed的花括号执行完之前,垃圾回收器是不会移动myobj对象的。
虽然使用fixed关键字可以解决声明类类型里面的值类型,但是因为堆里面的地址不能移动,所以堆里面就会有很多零散的内存,这样对性能会有影响,所以fixed使用的时间越短越好
6.提高程序的性能。
前面说了使用指针的原因其中之一是可以提高性能。怎么提高呢?
比如说现在要创建一个int(值类型)的数组。一般是int[] data=new int[10],这样创建,数组是保存在堆里面,大家都知道,栈的运行速度比堆快,那么我们把int(值类型)数组存到栈里面就会提高性能。这里就需要用到指针和stackalloc关键字。
int* pl=stackalloc int[10]
在这里只会给数组在栈里面分配内存,不会默认初始化任何值。
给数组赋值: pl[0]=1;//给数组的第一个位置赋值data[0]=1
pl[1]=2;//给数组的第二个位置赋值data[1]=2;
注意!!!!!
pl[20]=100; 这里是不会报错的,如果声明在引用类型这里会报错:下标越界,但是如果是指针这里就不会报错,
pl[20]这个地方是超过了我们之前所分配的区域,现在无法知道这个地方是否有值等等,反正在这个地址的地方被赋值了20.
所以!!!!!使用指针的时候最好是明白自己是在做什么,因为操作失误可能会出现一些古怪的异常
转自:https://blog.csdn.net/weixin_40068689/article/details/81778349