织梦CMS - 轻松建站从此开始!

罗索

当前位置: 主页>杂项技术>.NET(C#)>

【C#】不安全代码中的指针用法

jackyhwei 发布于 2010-10-21 21:51 点击:次 
有人说:"有的女人就像c#,长得很漂亮,但家务活不行。" 呵呵,其实我倒是认为不是那个女人不行,而是那个男人不行,征服不了那个女人。C#长得的确算漂亮,如果你驾驭了它,一样能让它服服帖帖做好家务。
TAG:

有人说:"有的女人就像c#,长得很漂亮,但家务活不行。"  呵呵,其实我倒是认为不是那个女人不行,而是那个男人不行,征服不了那个女人。C#长得的确算漂亮,如果你驾驭了它,一样能让它服服帖帖做好家务。

对于习惯C的程序员,Java之类的面向对象编程语言用着不是很爽,很多直接访问内存的操作行不通。而C#提供了指针的机制,以满足C族程序员的这点嗜好。不过刚开始了解到C#支持指针的时候,我也不以为然,总觉得这么搞显得不伦不类的。经过一番研究,慢慢感觉到了在一个有着强大基础类库的OO语言中使用指针的价值和威力。下面用代码展示一下使用指针的一些常用操作在C#中是怎么玩的,由于仅仅是展示,所以杂七杂八的代码全放在一起了。

  1. using System; 
  2.  
  3. namespace Sophy.UnsafeCode 
  4.     unsafe class Program 
  5.     { 
  6.         static void Main(string[] args) 
  7.         { 
  8.             //在栈上分配内存 
  9.             byte* arr_on_stack = stackalloc byte[100]; 
  10.  
  11.             //下标访问数组 
  12.             for (int i = 0; i < 100; i++) 
  13.             { 
  14.                 arr_on_stack[i] = 0; 
  15.             } 
  16.  
  17.             //在堆上分配内存 
  18.             fixed (byte* arr_on_heap = new byte[100]) 
  19.             { 
  20.                 //指针访问数组 
  21.                 for (int i = 0; i < 100; i++) 
  22.                 { 
  23.                     *(arr_on_heap + i) = 0; 
  24.                 } 
  25.             } 
  26.  
  27.             //在栈上分配一个结构体 
  28.             Point p = new Point(); 
  29.             //用结构体指针操作栈上的结构体 
  30.             Point* pp = &p; 
  31.             pp->x = 200; 
  32.             (*pp).y = 300; 
  33.  
  34.             //在堆上分配一个结构体 
  35.             fixed (byte* bs = new byte[sizeof(Point)]) 
  36.             { 
  37.                 //用结构体指针操作堆上的结构体 
  38.                 Point* ph = (Point*)bs; 
  39.                 (*ph).x = 400; 
  40.                 ph->y = 500; 
  41.             } 
  42.  
  43. //打印结构体内存地址 
  44. Console.WriteLine("pp Memory Address: 0x{0:X}.", ((int)pp).ToString()); 
  45.  
  46. //识别CPU字节序 
  47.             pp->x = 1; 
  48.             byte* pb = (byte*)&(pp->x); 
  49.             if (1 == *pb) 
  50.             { 
  51.                 Console.WriteLine("Your CPU is little endian."); 
  52.             } 
  53.             else if (1 == *(pb + sizeof(int) - 1)) 
  54.             { 
  55.                 Console.WriteLine("Your CPU is big endian."); 
  56.             } 
  57.             else 
  58.             { 
  59.                 Console.WriteLine("Unkown."); 
  60.             } 
  61.         } 
  62.     } 
  63.  
  64.     unsafe struct Point 
  65.     { 
  66.         public int x; 
  67.         public int y; 
  68.     } 

 

在C#中想要使用指针,要给类型、方法或者代码段加上unsafe关键字,并且编译的时候要加上/unsafe选项。在Visual Studio 2005中,勾上“项目属性->生成”里的“允许不安全代码”,编译时就会自动加上/unsafe选项。

    C#中的指针只能指向值类型,并且值类型中不能含有引用类型。如果允许指针指向引用类型,那将是非常令人迷惑的事情。也许你注意到了这行代码:

     fixed (byte* bs = new byte[sizeof(Point)])

     {

     }

     它把一个数组赋给了一个指针变量,数组是引用类型,那不是和上面说的矛盾了吗?其实我认为是编译器做了特殊处理,在这里直接将数组的地址赋给了指针变量。一个简单的fixed关键字,编译器在背后肯定做了不少事情。因为引用类型是在托管堆中分配的,受运行库管理,当内存中碎片太多时,垃圾回收器可能会启动内存压缩,有可能将数组移动到别的地方,这时指针指向的就不是原来的数组了,所以fixed作用还在于,把引用类型的数组“钉”在内存的那个位置上,不允许垃圾回收器移动,直到代码执行到fixed后面两个大括号之外为止。

http://www.cnblogs.com/hananbaum/archive/2008/10/30/1323364.html

(hananbaum)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201010/10348.html]
本文出处:博客园 作者:hananbaum
顶一下
(2)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容