.NET 数据类型之指针类型(type*)
- 指针类型
在不安全的上下文中,类型可以是指针类型以及值类型或引用类型。
指针类型不继承 object,并且指针类型与 object 之间不存在转换。此外,装箱和取消装箱不支持指针。但是,允许在不同指针类型之间以及指针类型与整型之间进行转换。
当在同一个声明中声明多个指针时,* 仅与基础类型一起使用,而不是作为每个指针名称的前缀。
指针不能指向引用或包含引用的结构,因为即使有指针指向对象引用,该对象引用也可能会被执行垃圾回收。GC 并不注意是否有任何类型的指针指向对象。
- 语法
type* identifier;void* identifier;
int* p1, p2, p3;
int number;int* p = &number;
char* charPointer = stackalloc char[123];for (int i = 65; i < 123; i++){charPointer[i] = (char)i;}
|
- 指针类型声明
示例 | 说明 |
---|---|
int* p |
p 是指向整数的指针 |
int** p |
p 是指向整数的指针的指针 |
int*[] p |
p 是指向整数的指针的一维数组 |
char* p |
p 是指向字符的指针 |
void* p |
p 是指向未知类型的指针 |
- 指针相关的运算符和语句
运算符/语句 | 用途 |
---|---|
* |
执行指针间接寻址。 |
-> |
通过指针访问结构的成员。 |
[] |
对指针建立索引。 |
& |
获取变量的地址。 |
++ 和 -- |
递增或递减指针。 |
加、减 |
执行指针算法。 |
==、!=、<、>、<= 和 >= |
比较指针。 |
stackalloc |
在堆栈上分配内存。 |
fixed 语句 |
临时固定变量以便可以找到其地址。 |
- 指针转换
-
- 隐式指针转换
从 | 到 |
---|---|
任何指针类型 |
void* |
null |
任何指针类型 |
-
- 显示指针转换
从 | 到 |
---|---|
任何指针类型 |
所有其他指针类型 |
sbyte、byte、short、ushort、int、uint、long 或 ulong |
任何指针类型 |
任何指针类型 |
sbyte、byte、short、ushort、int、uint、long 或 ulong |
- 代码示例
-
- 指针访问成员
struct CoOrds
{
public int x;
public int y;
}
class AccessMembers
{
static void Main()
{
CoOrds home;
unsafe
{
CoOrds* p = &home;
p->x = 25;
p->y = 12;
System.Console.WriteLine("The coordinates are: x={0}, y={1}", p->x, p->y );
}
}
}
|
-
- 指针访问数组元素
class Pointers
{
unsafe static void Main()
{
char* charPointer = stackalloc char[123];
for (int i = 65; i < 123; i++)
{
charPointer[i] = (char)i;
}
System.Console.WriteLine("Uppercase letters:");
for (int i = 65; i < 91; i++)
{
System.Console.Write(charPointer[i]);
}
System.Console.WriteLine();
System.Console.WriteLine("Lowercase letters:");
for (int i = 97; i < 123; i++)
{
System.Console.Write(charPointer[i]);
}
}
}
|
-
- 指针复制字节数组
class TestCopy
{
static unsafe void Copy(byte[] src, int srcIndex, byte[] dst, int dstIndex, int count)
{
if (src == null || srcIndex < 0 ||
dst == null || dstIndex < 0 || count < 0)
{
throw new System.ArgumentException();
}
int srcLen = src.Length;
int dstLen = dst.Length;
if (srcLen - srcIndex < count || dstLen - dstIndex < count)
{
throw new System.ArgumentException();
}
fixed (byte* pSrc = src, pDst = dst)
{
byte* ps = pSrc;
byte* pd = pDst;
for (int i = 0 ; i < count / 4 ; i++)
{
*((int*)pd) = *((int*)ps);
pd += 4;
ps += 4;
}
for (int i = 0; i < count % 4 ; i++)
{
*pd = *ps;
pd++;
ps++;
}
}
}
static void Main()
{
byte[] a = new byte[100];
byte[] b = new byte[100];
for (int i = 0; i < 100; ++i)
{
a[i] = (byte)i;
}
Copy(a, 0, b, 0, 100);
System.Console.WriteLine("The first 10 elements are:");
for (int i = 0; i < 10; ++i)
{
System.Console.Write(b[i] + " ");
}
System.Console.WriteLine("\n");
}
}
|