C#中指针的用法

(*) unsafe 和 fixed

unsafe
{
    int[] array = new int[10];
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = i;
    }
    fixed (int* p = array)
    {
        for (int i = 0; i < array.Length; i++)
        {
            System.Console.WriteLine(p[i]);
        }
    }
}

指针在c#中是不提倡使用的,有关指针的操作被认为是不安全的(unsafe)。因此运行这段代码之前,先要改一个地方,否则编译不过无法运行。
修改方法:在右侧的solution Explorer中找到你的项目,在项目图标(绿色)上点右键,选最后一项properties,然后在Build标签页里把Allow unsafe code勾选上。之后这段代码就可以运行了,你会看到,上面这段代码可以像C语言那样用指针操纵数组。但前提是必须有fixed (int* p = array),它的意思是让p固定指向数组array,不允许改动。因为C#的自动垃圾回收机制会允许已经分配的内存在运行时进行位置调整,如果那样,p可能一开始指的是array,但后来array的位置被调整到别的位置后,p指向的就不是array了。所以要加一个fixed关键字,把它定在那里一动不动,之后的操作才有保障。

另有两点需要注意:

1)指针的使用必须放在unsafe的区域里;unsafe关键字也可作为类或方法的修饰符。

2)fixed (int* p = array)中,p的定义不能写在别处,而且fixed关键字也只能在unsafe区域里使用。

(*) 略简洁的unsafe写法

class Program
    {
        unsafe public static UInt16 Htons(UInt16 src)
        {
            UInt16 dest;
            // 不能照搬C的源代码,因为有些类型长度不一样,如char(2字节),long(8字节)
            // ((char*)&dest)[0] = ((char*)&src)[1];
            // ((char*)&dest)[1] = ((char*)&src)[0];
            ((byte*)&dest)[0] = ((byte*)&src)[1];
            ((byte*)&dest)[1] = ((byte*)&src)[0];
            return dest;
        }

        public static UInt16 ConciseHtons(UInt16 src)
        {
            UInt16 dest;
            unsafe
            {
                ((byte*)&dest)[0] = ((byte*)&src)[1];
                ((byte*)&dest)[1] = ((byte*)&src)[0];
            }
            return dest;
        }

        static void Main()
        {
            UInt16 val = 1;

            // 如果方法是unsafe的,则必须在unsafe block里调用
            unsafe
            {
                val = Htons(val);
            }
            Console.WriteLine(val);

            // 更简洁的写法是把unsafe block写在函数内部
            val = ConciseHtons(val);
            Console.WriteLine(val);
        }
    }

(*) stackallocstackalloc的用处仅仅是把数组分配在栈上(默认是分配在托管堆上的)。

class MyClass
    {
        public int val;
    }

    class Program
    {
        static void Main()
        {
            unsafe
            {
                MyClass *p = stackalloc MyClass[1]; // Error!! 如果类型要放在托管堆上则不行,如果MyClass是struct就OK了
                p->val = 1;

                int *iArray = stackalloc int[100];  // OK,在栈上创建数组, int类型本身就是放在栈上的
            }
        }
    }

注意:指针指向的内存一定要固定。凡是C#里的引用类型(一切类型的数组都是引用类型)都是分配在托管堆上的,都不固定。有两种方法强制固定,一种是用stackalloc分配在栈上,另一种是用fixed分配在堆上。

时间: 2024-10-26 16:59:12

C#中指针的用法的相关文章

第22篇 js中的this指针的用法

前面把js的相关知识总结了下,今天把js中的上下文的this,对于强类型语言,this的用法非常的单一,因为他们没有js特有的动态绑定. 首先看下面代码: function funcA() { this.name = "hello"; console.log(this.name); this.show = function() { console.log(this.name); } } funcA();// 1.hello var a = new funcA();//2.hello a

C中函数指针的用法

理解了C中的声明和指针的话题后再来看函数指针的用法就很容易了. C中函数指针主要有两个用途: 1.作为参数传递给另外一个函数(即作为回调函数) 2.转换表(jump table) 下面分别来介绍作为回调函数的用法和作为转换表的用法 1.回调函数 在链表的查找中使查找函数与类型无关 /*在一个单链表中查找一个指定值的函数.它的参数是一个指向链表第一个节点的指针 * 一个指向我们需要查找的值的指针和一个函数指针,它所指向的函数用于比较存储于链表中的类型的值*/ #include <stdio.h>

C#中this指针的用法示例

这篇文章主要介绍了C#中this指针的用法,对初学者而言是非常重要的概念,必须加以熟练掌握,需要的朋友可以参考下. 本文实例展示了C#中this指针的用法,对于初学者进一步牢固掌握C#有很大帮助,具体内容如下: 一.this指针是什么: 这里有一些面向对象编程的概念需要说明:类(Class)的概念和对象(Object)的概念类是对事物概括,也是C#编码时所有代码归属的基本单位:而对象是对类的实例化,也就是C#里new方法的返回值.写代码是不能直接用操作类,而只能先实例化类,然后我们用这个类被实例

[Perl系列—] 2. Perl 中的引用用法

Perl 中的引用,为什么要使用引用? 对于熟悉C语言的开发者来说, 指针这个概念一定不陌生. Perl 的引用就是指针,可以指向变量.数组.哈希表甚至子程序. Perl5中的两种Perl引用类型为硬Perl引用和符号Perl引用.符号Perl引用含有变量的名字,它对运行时创建变量名并定位很有用,基本上,符号Perl引用就象文件名或UNIX系统中的软链接.而硬Perl引用则象文件系统中的硬链接. Perl4只允许符号Perl引用,给使用造成一些困难.例如,只允许通过名字对包的符号名哈希表(名为_

转 浅谈C++中指针和引用的区别

浅谈C++中指针和引用的区别 浅谈C++中指针和引用的区别 指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法. 1.指针和引用的定义和性质区别: (1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元:而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已.如: int a=1;int *p=&a; int a=1;int &b=a; 上面定义了一个整形变量和一个指针变量p,该指针变量指向a

C++ 浅谈C++中指针和引用

浅谈C++中指针和引用的区别 指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法. 1.指针和引用的定义和性质区别: (1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元:而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已.如: int a=1;int *p=&a; int a=1;int &b=a; 上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单

c++中vector的用法详解

c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的. 用法: 1.文件包含: 首先在程序开头处加上#include<vector>以包含所需要的类文件vector 还有一定要加上using namespace std; 2.变量声明: 2.1 例:声明一个int向量以替代一维的数组:vector <int> a;(等于声明了一个

C++中的const用法(2)

前面写过一篇博客介绍const用法:C++中的const用法 今天发现有个忙点,特此补充. 我们知道,一般const修饰指针时有三种情况. <span style="font-size:18px;">const int *p;</span> 这表示p指向一个int型的const变量,但是指针本身并不是const. int a = 0; int *const p = &a; 这种情况表示指针是const,一旦初始化不能指向另外的数据. int a = 0;

[转]c++ 中__declspec 的用法

c++ 中__declspec 的用法 转载地址:http://www.cnblogs.com/ylhome/archive/2010/07/10/1774770.html c++ 中__declspec 的用法 语法说明: __declspec ( extended-decl-modifier-seq ) 扩展修饰符: 1:align(#) 用__declspec(align(#))精确控制用户自定数据的对齐方式 ,#是对齐值. e.g __declspec(align(32)) struct