
- 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# - 檔案 I/O
- C# 高階教程
- C# - 屬性
- C# - 反射
- C# - 屬性
- C# - 索引器
- C# - 委託
- C# - 事件
- C# - 集合
- C# - 泛型
- C# - 匿名方法
- C# - 不安全程式碼
- C# - 多執行緒
- C# 有用資源
- C# - 常見問題解答
- C# - 快速指南
- C# - 有用資源
- C# - 討論
C# - 不安全程式碼
當使用 `unsafe` 修飾符標記程式碼塊或函式時,C# 允許使用指標變數。`不安全程式碼` 或非託管程式碼是指使用`指標`變數的程式碼塊。
注意 − 要在 codingground 上執行本章中提到的程式,請在 專案 >> 編譯選項 >> 編譯命令 中設定編譯選項為:
mcs *.cs -out:main.exe -unsafe
指標
一個`指標`是一個變數,其值是另一個變數的地址,即記憶體位置的直接地址。與任何變數或常量類似,您必須在使用指標儲存任何變數地址之前宣告它。
指標宣告的一般形式為:
type *var-name;
以下是有效的指標宣告:
int *ip; /* pointer to an integer */ double *dp; /* pointer to a double */ float *fp; /* pointer to a float */ char *ch /* pointer to a character */
以下示例說明了在 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
無需將整個方法宣告為不安全,您也可以將程式碼的一部分宣告為不安全。下一節中的示例演示了這一點。
使用指標檢索資料值
您可以使用 `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) /* let us have array address in pointer */ 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` 命令列開關。
例如,要從命令列編譯名為 prog1.cs 的包含不安全程式碼的程式,請使用以下命令:
csc /unsafe prog1.cs
如果您使用的是 Visual Studio IDE,則需要在專案屬性中啟用不安全程式碼的使用。
方法如下:
雙擊解決方案資源管理器中的屬性節點開啟專案屬性。
單擊生成選項卡。
選擇“允許不安全程式碼”選項。