class f2011fq1d
{
unsafe public static void Main()
{
int a = 2;
int b = 4;
int* p;
int* q;
int[] ia = { 11, 12, 13 };
p = &a; q = &b;
Console.WriteLine(*p + a);
Console.WriteLine(*q / *p);
Console.WriteLine(*&a + *&b * 2);
*p = a + *q;
Console.WriteLine(a + *q);
fixed (int* r = ia)
{
Console.WriteLine(*r + 3);
}
}
}
在这段代码中,我对一些语法感到困惑。例如,int* p
和p = &a
做什么?最后一部分是fixed (int* r = ia)
,这是做什么的?
在源代码中,它还会打印一些值,有人可以解释正在打印的内容吗?
答案 0 :(得分:7)
您正在使用指针和“运算符地址”这些通常与C / C ++相关的功能,但在unsafe
代码块中的C#代码中可用。我建议对这个概念进行一些一般性的研究,因为单独理解语法不足以有效地使用它们。我会解释几行;
int * p; //a pointer (the address of) 4 bytes of memory for an int
int a = 5; // normal allocation/initialization of int
p = &a; //sets p to the address of a. Since p is a pointer, it holds an address
// ampersand is the 'address of operator', it returns and address. so this assignment works
p = a // will not compile. int* != int
p == 5 // will not compile, int* != int
*p == 5 // true. *pointer dereferences the pointer returning the value
// found at the address p points to which is 5 so this is true.
int * q = &a; // another pointer to the memory containing a
p == q // true, both pointers contain the same value, some address which is usually displayed in hex like 0xFF110AB2
指针的更常见用法是类似的;
int *p;
// do something to get a length for an integer array at runtime
p = new int[size];
// now I've allocated an array based on information found at run time!
上述操作在C / C ++中非常常见,完全是必要的。在C#中,没有必要这样做。它已经在幕后为你完成,它永远不会出错(比如没有释放我刚刚分配的内存)。
答案 1 :(得分:1)
int* p
声明一个名为p
的变量,它是一个指向int的指针。
p = &a
会导致p
指向内存中与a
相同的位置。
Pointer types (C# Programming Guide)可能是一个很好的起点。
答案 2 :(得分:1)
使用unsafe
代码,C#允许您使用指针和地址,例如C. int *p
声明指向int
的指针。 p = &a
,取a
的地址并将其存储在p
。
fixed
可防止垃圾收集器移动数据。
请参阅http://msdn.microsoft.com/en-us/library/chfa2zb8(v=vs.100).aspx和http://msdn.microsoft.com/en-us/library/f58wzh21(v=vs.100).aspx
答案 3 :(得分:1)
在这段代码中,我对一些语法感到困惑。例如......
我会尝试一次解决这些问题(没有双关语)
int * p
是什么
这声明了一个名为'p'的局部变量,其类型是指向int的指针。因此,当将此变量分配给内存地址时,它将读取4个字节,就像它们是int32一样。
...和p =& a
右边的'& a'被读作“a的地址”,意思是取我们分配给局部变量'a'的存储位置。将它分配给已经声明的int指针'p',然后我们可以读'p'来获得实际存储在变量'a'中的值。
最后一部分是固定的(int * r = ia),那会怎么做?
这非常类似于将p分配给a的地址,除了没有“地址”前缀。这是因为变量'ia'的类型是一个被隐式处理的数组,就像它是一个指针一样。因此,此语句声明一个int指针'r'并将其分配给数组'ia'中第一个项的地址。
以下是一些注意事项:
if (*p == 2) ...
以'*'为前缀的指针将取消引用该指针,并将其视为指针类型的变量。因此,在我们的示例中,取消引用“p”指向变量“a”将导致值存储在“a”,2中。
*p = 100;
就像在'p'指向的地址读取值一样,我们也可以写一个新值。只需取消引用指针并为其指定一个新值。
*&a
这只是为了让某些人感到困惑。如上所述,它通过前缀'&'获取'a'的地址,但随后使用'*'前缀取消引用地址。这只是评估为'a',并且可以省略两个前缀而不改变行为。