Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么可以';我们在C#中做IntPtr和UIntPtr算法吗?_C#_.net_Intptr - Fatal编程技术网

为什么可以';我们在C#中做IntPtr和UIntPtr算法吗?

为什么可以';我们在C#中做IntPtr和UIntPtr算法吗?,c#,.net,intptr,C#,.net,Intptr,这是一个看起来很简单的问题: 既然本机大小的整数最适合算术,为什么C#(或任何其他.NET语言)不支持本机大小的IntPtr和UIntPtr的算术呢 理想情况下,您可以编写如下代码: for (IntPtr i = 1; i < arr.Length; i += 2) //arr.Length should also return IntPtr { arr[i - 1] += arr[i]; //something random like this } for(IntPtr i=

这是一个看起来很简单的问题:

既然本机大小的整数最适合算术,为什么C#(或任何其他.NET语言)不支持本机大小的
IntPtr
UIntPtr
的算术呢

理想情况下,您可以编写如下代码:

for (IntPtr i = 1; i < arr.Length; i += 2) //arr.Length should also return IntPtr
{
    arr[i - 1] += arr[i]; //something random like this
}
for(IntPtr i=1;i
因此,它可以在32位和64位平台上工作。(目前,您必须使用
long


编辑:


我没有用这些作为指针(甚至没有提到“指针”这个词)!它们可以被视为MSIL中的
native int
和C的
stdint.h
中的
intptr\t
的C对应物,它们是整数,而不是指针。

因为这不是处理内存寻址的“安全”方法。指针运算会导致各种错误和内存寻址问题,C#是专门为避免这些问题而设计的。

在.NET 4中,支持
IntPtr
类型的左手操作数和整数类型的右手操作数(
int
long
等)之间的运算

[编辑]: 正如其他人所说,它们被设计为用本地语言表示指针(顾名思义是IntPtr)。可以说您将它们用作本机整数而不是指针,但您不能忽视,整数本机大小之所以重要的主要原因之一是用作指针。如果您执行的是数学运算,或其他与代码所运行的处理器和内存体系结构无关的通用函数,可以说,使用诸如
int
long
之类的类型更有用、更直观,因为在任何情况下,无论硬件如何,您都知道它们的固定大小和上下限


正如类型
IntPtr
设计用于表示本机指针一样,算术运算设计用于表示将对指针执行的逻辑数学运算:向本机指针添加一些整数偏移量以达到新的本机指针(并不是说不支持添加两个
IntPtr
s,也不支持将
IntPtr
用作右侧操作数)。

也许本机大小的整数可以实现最快的算术运算,但它们肯定不能实现最无错误的程序

就我个人而言,我讨厌使用整数类型编程,当我坐下来开始键入时,我不知道这些整数类型的大小(我看着你,C++),我当然更喜欢CLR类型给你带来的平和,而不是使用针对平台定制的CPU指令可能带来的非常可疑和肯定有条件的性能优势

还要考虑到JIT编译器可以针对进程运行的体系结构进行优化,这与“常规”编译器不同,后者必须生成机器代码,而不需要访问这些信息。因此,JIT编译器生成代码的速度可能会一样快,因为它知道的更多


我想我不是唯一一个这样想的人,所以这可能是有原因的。

.Net Framework试图不引入无法解释的操作。例如,没有DateTime+DateTime,因为没有两个日期之和的概念。同样的推理也适用于指针类型-没有两个指针之和的概念。事实上IntPtr存储为与平台相关的int值其实并不重要-还有许多其他类型在内部存储为基本值(DateTime也可以表示为long)。

我可以想出IntPtr(或UIntPtr)的一个原因可能很有用:访问数组元素需要本机大小的整数。虽然本机整数从不向程序员公开,但它们在IL中内部使用。C中类似于
some_array[index]
的内容实际上会编译为
some_array[(int)checked((IntPtr)index)]
在IL中。在使用ILSpy分解自己的代码后,我注意到了这一点。(在我的代码中,
索引
变量是64位的。)为了验证反汇编程序没有出错,Microsoft自己的ILDASM工具显示我的程序集中存在
conv.u
conv.i
指令。这些指令将整数转换为系统的本机表示形式。我不知道所有这些转换指令对性能的影响,但希望JIT足够聪明,可以优化性能损失;如果不是,下一个最好的方法是允许在不进行转换的情况下操作本机整数(在我看来,这可能是使用本机类型的主要动机)

目前,F#语言允许在算术中使用
nativent
及其无符号对应项。但是,数组只能通过F#中的
int
进行索引,这意味着
nativent
对于索引数组不是很有用


如果它真的让你很烦恼,那就编写你自己的编译器,解除对本机整数使用的限制,创建你自己的语言,用IL编写代码,或者在编译后调整IL。我个人认为,使用本机int挤出额外性能或节省内存是个坏主意。如果你想让代码像glo一样适合系统ve,您最好使用支持处理器内部函数的低级语言。

+1我不知道!!=O但我的意思是完全使用
IntPtr
,而不是在混合中加入另一个固定大小的整数。更新了我关于为什么使用固定大小的整数适用于situation@jeffora:那么你基本上是在说我明白,在任何情况下这都是有用的,对吗?虽然我觉得难以接受,但这似乎是一个非常合理的解释