Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.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#和C+中声明数组有什么区别+;? C++中的数组声明将为三个整数分配一个内存块。_C#_Arrays - Fatal编程技术网

在C#和C+中声明数组有什么区别+;? C++中的数组声明将为三个整数分配一个内存块。

在C#和C+中声明数组有什么区别+;? C++中的数组声明将为三个整数分配一个内存块。,c#,arrays,C#,Arrays,我可以假设c语言也是如此,但由于以下事实,我不能 c#中的每个变量都是struct、class或enum,因为Array是一个类,所以arr应该是class Array的对象。 Intellisense还显示,arr有许多成员函数,与类数组的函数相同,但数组是一个抽象类,因为我们不能实例化抽象类,所以arr可以是可能实现数组类的任何其他类的对象 如果我的推断是正确的,我想知道 arr是哪个类的对象 如果我的推断是错误的 我想知道我错在哪里 哪个类数组是的对象 c#中的每个变量都是结构、类或枚举

我可以假设c语言也是如此,但由于以下事实,我不能

c#中的每个变量都是struct、class或enum,因为Array是一个类,所以arr应该是class Array的对象。 Intellisense还显示,arr有许多成员函数,与类数组的函数相同,但数组是一个抽象类,因为我们不能实例化抽象类,所以arr可以是可能实现数组类的任何其他类的对象

如果我的推断是正确的,我想知道

  • arr是哪个类的对象
  • 如果我的推断是错误的

  • 我想知道我错在哪里
  • 哪个类数组是的对象
  • c#中的每个变量都是结构、类或枚举

    C#中的每个变量都有一个类型,该类型要么是值类型,要么是引用类型。在某些情况下,所有值类型都分类为
    struct
    ,所有引用类型都分类为
    class
    ,但这并不常见。如果这就是您的意思,那么“或枚举”是多余的,因为它们是值类型。如果这不是您的意思,那么您会忽略一些情况,例如接口类型

    arr是哪个类的对象

    arr
    是类型为
    int[]
    的对象
    int[]
    是一种引用类型,它派生自
    System.Array
    ,但将其称为类类型是一种延伸,除非调用所有引用类型类类型

    为什么c#的设计者使用上述语法,为什么他们不使用简单的ClassName ObjectName=new ClassName()和数组呢


    “ClassName”是
    int[]
    ,因此您的建议将导致
    int[]arr=new int[](3)。这更为冗长,从其他语言来到C语言的人看起来并不熟悉,实际上也没有设法简化语言:该语言仍然需要有特殊的规则来确定在哪里可以使用
    [
    ]

    很难比较这两种语言,它们几乎没有共同点。C++继承了C语言的数组语法和行为。设计时只考虑了一个目标,只考虑了尽可能快的速度。您使用的单词“allocate”与运行时发生的情况已经很不匹配,int[3]语法只保留了空间。发生这种情况的确切位置取决于声明的位置,在函数内部它将在堆栈帧上保留空间,在函数外部它将在数据段中保留空间

    在没有执行保证的情况下,元素不会初始化,运行时不会跟踪数组的大小,也不会进行索引检查。以尽可能快的速度,发布数十亿个bug和数万个恶意软件攻击的功能。在C或C++程序中,缓冲区溢出是一个标准问题,当它损坏内存、随机覆盖其他变量或函数的返回地址时,产生非常难以诊断的错误。或者用数据、恶意软件攻击向量来简单地使用程序。 当然不是C#方式。数组类型是.NET Framework中的引用类型,它们的存储总是从GC堆分配的。如果数组很小(小于85KB),则使用fast gen#0堆,否则使用大对象堆。抖动和CLR中有很多胶水,使它们尽可能快地保持静止,尽管它们保证:

    • 有专门的IL操作码来创建数组,抖动将其转换为直接调用CLR
    • 如果数组类型尚不存在(与比较),则此帮助函数将动态创建数组类型,从GC堆中分配存储并初始化对象,设置Length属性并初始化数组成员,使它们都具有默认(t)值
    • 再次访问代码中的数组元素会生成专用的IL操作码,如。抖动将它们转换为机器代码指令,用于检查数组边界并访问数组元素
    • 其他数组成员直接调用内部SZArrayHelper类,该类经过优化,可以为一维数组生成尽可能快的代码
    • jitter中的代码优化器寻找消除数组绑定检查的机会,当它可以从代码中看到索引表达式不能超出边界时,这是可能的。这通常是可能的,特别是当您使用foreach或编写使用数组的Length属性的for(;;)循环时,那么数组访问的速度就与C中的等效速度一样快
    • 垃圾收集器具有数组的内置知识,它在压缩堆时重新排列引用类型的数组元素,以便可以在迭代数组的代码中顺序访问它们。在现代处理器上,这一点非常重要,因为现代处理器依靠CPU缓存来快速访问内存。这是托管代码可以轻松地击败本机C或C++代码的地方,本地内存分配在发生的任何地方都被卡住。
    在没有安全保证的情况下,C#仍然有语法来模拟C数组。当发现数组代码位于程序的关键路径中时,可以使用它们。这些构造要求您使用不安全关键字,它们与等效的C代码具有相同的问题:

    • 关键字可用于从堆栈帧而不是GC堆分配数组。就像C程序中的局部数组变量一样。当您的C#代码中的本地数组产生太多垃圾,并且GC集合开始支配您的程序的执行时间时,这是一种回退
    • 关键字可用于声明无需边界检查即可访问的数组。stackalloc的另一种选择是用于需要在方法调用后存活的数组。当你得不到inde时,这是一种退路
      int[] arr = new int[3]; // C#
      int arr[3]; //C++