当使用指向数组的指针时,我总是使用索引器访问元素,例如myPtr[i] = stuff
;但是,我最近查看BitConverter
's implementation并发现通过执行*(myPtr + i) = stuff
来访问元素。
我认为这很奇怪,因为这两种方法(据我所知)完全相同,也就是说,它们返回myPtr + i
的地址,除了(在我看来)索引器方法看起来很多更具可读性。
那么为什么微软选择以他们的方式增加指针,两种方法之间有什么区别(是否有性能优势)?
答案 0 :(得分:4)
如你所说,他们做同样的事情。
实际上,在访问int*
时,ptr[i]
和*(ptr + i)
语法都会跳过边界检查,如果i
是*(ptr + index)
,则指向数组范围外的一些内存大于数组长度。
我很确定C#和C ++继承了使用C语言的{{1}}语法对数组指针的索引访问。我很确定这是两种语法都可用的唯一原因。< / p>
答案 1 :(得分:2)
来自CSharp Language Specification(18.5.3):
形式P [E]的指针元素访问精确地评估为*(P + E)。 (...)指针元素访问运算符不检查越界错误,并且访问越界元素时的行为未定义。这与C和C ++相同。
没有差异。
答案 2 :(得分:1)
为了澄清数组的[]
运算符和指针(在dcastro的答案下讨论)之间的区别,您可以检查以下代码的输出。
unsafe {
int[] arr = new[] { 1, 2 };
fixed(int* ptr = arr) {
for(int i = 0; i < arr.Length + 1; i++) {
try { System.Console.WriteLine(*(ptr + i)); } catch(Exception e) { System.Console.WriteLine(e.Message); }
try { System.Console.WriteLine(ptr[i]); } catch (Exception e) { System.Console.WriteLine(e.Message); }
try { System.Console.WriteLine(arr[i]); } catch (Exception e) { System.Console.WriteLine(e.Message); }
}
}
}
输出
1
1
1
2
2
2
0
0
Index was outside the bounds of the array.