------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------
从大学刚开始接触编程语言C,就知道指针这个东西,用好了,得心应手,用不好,则整个编写的应用程序都会崩溃,为了保持类型安全,默认情况下,C# 不支持指针,然而C#通过使用 unsafe 关键字,可以定义不安全上下文,然后在不安全上下文中使用指针,在 C# 中,为了编译不安全代码,必须用 /unsafe 编译应用程序。
一、指针类型的声明
type* identifier;
void* identifier; // 允许但不推荐使用!
可以声明为指针类型的数据类型包括:
sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal 或 bool。
任何枚举类型。
任何指针类型。
仅包含非托管类型的字段的任何用户定义的结构类型。下面给出一个示例。
using System;
namespace CSharpPractice.Pointer
{
unsafe class VoidPointer
{
static void Main()
{
//pv 是指向未知类型的指针,pi 是指向整数的指针
//注意:一元间接寻址运算符“*”不能用于 void 指针
//使用强制转换将 void 指针转换为整数(int)指针类型
int i = 10;
void* pv = &i;
int* pi = (int*)pv;
Console.WriteLine("i={0}, pi={1:X},pv={2:X}, &i={3:X}, *pi={4}", i, (int)pi, (int)pv, (int)&i, *pi);
}
}
}
二、指针的操作
下面的示例给出的是不安全的上下文中针对指针执行的运算符和语句 。
using System;
namespace CSharpPractice.Pointer{
struct CoOrds // 平面坐标
{
public int x;
public int y;
}
unsafe class PointerOp
{
static void Main()
{
//(1)获取变量的地址和变量的值,并通过指针操作更改变量的值
int number=10;
// 将整数number的地址赋给指针变量pi:
int* pi = &number;
// 打印整数number原始的值:
Console.WriteLine("整数number原始的值 = {0}", number);
// 打印*p原始的值:
Console.WriteLine("*pi原始的值 = {0}", *pi);
// 打印pi的值(即整数number的地址):
Console.WriteLine("pi(即整数number的地址) = {0:X}", (int)pi);
// 通过指针操作更改整数number的值
*pi = 20;
// 打印*p的值:
Console.WriteLine("指针操作后*pi的值 = {0}", *pi);
// 打印整数number更改后的值:
Console.WriteLine("指针操作后整数number的值 = {0}", number);
//(2)通过指针访问成员
CoOrds school; // 学校坐标
CoOrds* p = &school;
p->x = 25; // 学校坐标x
p->y = 12; // 学校坐标y
Console.WriteLine("\n(p->x形式打印)学校的坐标值 : x={0}, y={1}", p->x, p->y);
//表达式 p->x 等效于表达式 (*p).x,使用这两个表达式可获得相同的结果
Console.WriteLine("(*p).x形式打印)学校的坐标值 : x={0}, y={1}", (*p).x, (*p).y);
//(3)通过指针访问数组元素
char* charPointer = stackalloc char[123]; //在堆栈上分配内存
for (int i = 65; i < 123; i++)
{
//charPointer[i] = (char)i; // 等价于 *(charPointer+i) = (char)i;
*(charPointer+i) = (char)i;
}
// 打印大写字母:
Console.WriteLine("\n大写字母:");
for (int i = 65; i < 91; i++)
{
//Console.Write(charPointer[i]); // 等价于 Console.Write(*(charPointer+i));
Console.Write(*(charPointer+i));
}
// 打印小写字母:
Console.WriteLine("\n小写字母:");
for (int i = 97; i < 123; i++)
{
Console.Write(charPointer[i]);
}
Console.WriteLine("\n");
//(4)递增和递减指针
// 通过将指针增加 int 的大小来遍历一个数组。
// 对于每一步,均显示数组元素的内容和地址。
int[] numbers = { 0, 1, 2, 3, 4 };
// 将数组地址赋给指针:
fixed (int* p1 = numbers) //临时固定一个变量,以获取其地址
{
// 遍历数组元素:
for (int* p2 = p1; p2 < p1 + numbers.Length; p2++)
{
Console.WriteLine("数组元素的内容:{0}, 地址:{1:X}", *p2, (int)p2);
}
}
//(5)使用算术运算符 + 和 - 来操作指针
int* memory = stackalloc int[30];
long* difference;
int* pi1 = &memory[4];
int* pi2 = &memory[10];
difference = (long*)(pi2 - pi1);
Console.WriteLine("\n指针(&memory[10]-&memory[4])相减的差为: {0}\n", (long)difference);
//(6)指针比较
int x = 234;
int y = 236;
int* px = &x;
int* py = &y;
Console.WriteLine("x为{0}, y为{1}, px为{2:X}, py为{3:X}", x ,y, (int)px, (int)py);
Console.WriteLine("指针比较:px>py为{0}, px<py为{1}", px > py, px < py);
}
}
}
关于指针的笔记就写到这里,其实要想学好指针,光这些基础编程是远远不够的,需要我们在做实际项目中去运用,怎么用,如何用,出现问题怎么解决都值得我们去思考。
------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------