主页
  • 主页
  • 分类
  • 热文
  • 教程
  • 面试
  • 标签
C#

C# 基础

C# 主页
C# 概述
C# 环境
C# 程序结构
C# 基本语法
C# 数据类型
C# 类型转换
C# 变量
C# 常量
C# 运算符
C# 决策结构
C# 循环结构
C# 封装
C# 方法
C# 可空类型
C# 数组
C# 字符串
C# 结构体
C# 枚举
C# 类
C# 继承
C# 多态性
C# 操作符重载
C# 接口
C# 命名空间
C# 预处理
C# 正则表达式
C# 异常
C# 文件与流

C# 高级

C# 属性(Attributes)
C# 反射
C# 属性(Properties)
C# 索引器
C# 委托
C# 事件
C# 集合
C# 泛型
C# 匿名方法
C# 不安全代码
C# 线程

基础

C# 主页
C# 概述
C# 环境
C# 程序结构
C# 基本语法
C# 数据类型
C# 类型转换
C# 变量
C# 常量
C# 运算符
C# 决策结构
C# 循环结构
C# 封装
C# 方法
C# 可空类型
C# 数组
C# 字符串
C# 结构体
C# 枚举
C# 类
C# 继承
C# 多态性
C# 操作符重载
C# 接口
C# 命名空间
C# 预处理
C# 正则表达式
C# 异常
C# 文件与流

高级

C# 属性(Attributes)
C# 反射
C# 属性(Properties)
C# 索引器
C# 委托
C# 事件
C# 集合
C# 泛型
C# 匿名方法
C# 不安全代码
C# 线程

C# 不安全代码


上一章 下一章

C# 中的指针

C# 允许在标记为 unsafe 修饰符的功能或代码块中使用指针变量。unsafe 代码或非托管代码是指使用指针变量的代码块。

注意:为了在 codingground 上执行本章中的程序,请在 Project >> Compile Options >> Compilation Command 中设置编译选项为 mcs *.cs -out:main.exe -unsafe

指针

指针是一个变量,它的值是另一个变量的地址,即内存位置的直接地址。如同任何变量或常量一样,在使用它存储任何变量地址之前,必须声明一个指针。

指针声明的一般形式是:

type *var-name;

以下是有效的指针声明:

int    *ip;    /* 指向一个整数的指针 */
double *dp;    /* 指向一个双精度浮点数的指针 */
float  *fp;    /* 指向一个单精度浮点数的指针 */
char   *ch;    /* 指向一个字符的指针 */

下面的例子演示了如何在 C# 中使用 unsafe 修饰符来使用指针:

using System;

namespace UnsafeCodeApplication {
   class Program {
      static unsafe void Main(string[] args) {
         int var = 20;
         int* p = &var;
         
         Console.WriteLine("Data is: {0} ",  var);
         Console.WriteLine("Address is: {0}",  (int)p);
         Console.ReadKey();
      }
   }
}

当上述代码被编译和执行时,它产生如下结果:

Data is: 20
Address is: 99215364

除了声明整个方法为 unsafe 外,你还可以声明部分代码为 unsafe。下面的示例展示了这一点。

通过指针获取数据值

你可以使用 ToString() 方法来获取存储在指针变量所指向的位置的数据。下面的例子演示了这一点:

using System;

namespace UnsafeCodeApplication {
   class Program {
      public static void Main() {
         unsafe {
            int var = 20;
            int* p = &var;
            
            Console.WriteLine("Data is: {0} " , var);
            Console.WriteLine("Data is: {0} " , p->ToString());
            Console.WriteLine("Address is: {0} " , (int)p);
         }
         Console.ReadKey();
      }
   }
}

当上述代码被编译和执行时,它产生如下结果:

Data is: 20
Data is: 20
Address is: 77128984

将指针作为方法参数传递

你可以将指针变量作为参数传递给方法。下面的例子演示了这一点:

using System;

namespace UnsafeCodeApplication {
   class TestPointer {
      public unsafe void swap(int* p, int *q) {
         int temp = *p;
         *p = *q;
         *q = temp;
      }
      public unsafe static void Main() {
         TestPointer p = new TestPointer();
         int var1 = 10;
         int var2 = 20;
         int* x = &var1;
         int* y = &var2;
         
         Console.WriteLine("Before Swap: var1:{0}, var2: {1}", var1, var2);
         p.swap(x, y);

         Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
         Console.ReadKey();
      }
   }
}

当上述代码被编译和执行时,它产生如下结果:

Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10

使用指针访问数组元素

在 C# 中,数组名和指向与数组数据相同类型的数据的指针并不是相同的变量类型。例如,int *p 和 int[] p 并不是同一种类型。你可以递增指针变量 p 因为它不是固定在内存中的,但是数组地址在内存中是固定的,因此不能递增。

因此,如果你想使用指针变量来访问数组数据,就像我们在 C 或 C++ 中传统上所做的那样(请检查:C 指针),你需要使用 fixed 关键字来固定这个指针。

下面的例子演示了这一点:

using System;

namespace UnsafeCodeApplication {
   class TestPointer {
      public unsafe static void Main() {
         int[]  list = {10, 100, 200};
         fixed(int *ptr = list)
         
         /* 让我们把数组地址放在指针里 */
         for ( int i = 0; i < 3; i++) {
            Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
            Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
         }
         
         Console.ReadKey();
      }
   }
}

当上述代码被编译和执行时,它产生如下结果:

Address of list[0] = 31627168
Value of list[0] = 10
Address of list[1] = 31627172
Value of list[1] = 100
Address of list[2] = 31627176
Value of list[2] = 200

编译 unsafe 代码

对于编译 unsafe 代码,你需要在命令行编译器中指定 /unsafe 命令行开关。

例如,要编译一个含有 unsafe 代码的名为 prog1.cs 的程序,从命令行输入命令:

csc /unsafe prog1.cs

如果你正在使用 Visual Studio IDE,则需要在项目属性中启用 unsafe 代码的使用。

为此,请执行以下操作:

  1. 在解决方案资源管理器中双击属性节点以打开项目属性。
  2. 点击构建选项卡。
  3. 选择“允许 unsafe 代码”的选项。
上一章 下一章
阅读号二维码

关注阅读号

联系二维码

联系我们

© 2024 Yoagoa. All rights reserved.

粤ICP备18007391号

站点地图