Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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++ 为什么不';t内置阵列是否安全?_C++_Arrays - Fatal编程技术网

C++ 为什么不';t内置阵列是否安全?

C++ 为什么不';t内置阵列是否安全?,c++,arrays,C++,Arrays,作者的书(ISBN 0-321-71411-3/978-0-321-71411-4)提到: [std::]array是内置阵列的一种更安全、更易于使用的替代方案 内置阵列有什么问题?具有安全的at成员功能。它还有开始,结束,大小,您可以使用它们使代码更安全 原始阵列没有这种功能。(特别是,当原始数组衰减为指针时(例如,当作为参数传递时),将丢失所有大小信息,这些信息保存在std::array类型中,因为它是一个以大小为参数的模板) 一个优秀的优化C++11编译器将处理std::array(或对它

作者的书(ISBN 0-321-71411-3/978-0-321-71411-4)提到:

[std::]array
是内置阵列的一种更安全、更易于使用的替代方案

内置阵列有什么问题?

具有安全的
at
成员功能。它还有
开始
结束
大小
,您可以使用它们使代码更安全

原始阵列没有这种功能。(特别是,当原始数组衰减为指针时(例如,当作为参数传递时),将丢失所有大小信息,这些信息保存在
std::array
类型中,因为它是一个以大小为参数的模板)


一个优秀的优化C++11编译器将处理
std::array
(或对它们的引用)和原始数组一样高效。

很难判断作者的意思,但我猜他们指的是关于本机数组的以下事实:

  • 它们是生的
    没有
    。在
    成员函数中,您可以使用边界检查进行元素访问,尽管我反对您通常不希望这样做。要么访问已知存在的元素,要么进行迭代(使用
    std::array
    和本机数组也可以很好地实现这一点);如果您不知道元素存在,那么边界检查访问器已经是一种非常糟糕的确定方法,因为它对代码流使用了错误的工具,并且会带来严重的性能损失

  • 它们可能令人困惑
    新手往往会忘记数组名称的衰减,将数组“按值”传递到函数中,然后在随后的指针上执行
    sizeof
    ;这通常并不“不安全”,但会产生bug

  • 无法分配它们
    同样,这并不是天生的不安全,但它会导致愚蠢的人用多级指针和大量动态分配编写愚蠢的代码,然后失去记忆的踪迹,犯下各种罪行

假设作者推荐的是
std::array
,那是因为它“修复”了上述所有内容,默认情况下会生成更好的代码

但相比之下,本机阵列是否天生就“不安全”?不,我不会这么说

  • 内置数组是一个连续的字节块,通常位于堆栈上。您确实没有合适的方法来保存有关数组、其边界或状态的有用信息<代码>标准::数组保留此信息

  • 内置数组在从/传递到函数时会衰减为指针。这可能导致:

    • 传递内置数组时,传递一个原始指针。指针不保留有关数组大小的任何信息。您必须传递数组的大小,从而使代码变得丑陋<代码>标准::数组可以作为引用、复制或移动传递

    • 无法返回内置数组,如果在该函数作用域中声明了数组,则最终将返回指向局部变量的指针。
      std::array
      可以安全返回,因为它是一个对象,其生存期是自动管理的

  • 在内置数组上,您无法真正执行一些有用的操作,例如分配、移动或复制它们。您将结束为每个内置数组编写自定义函数(可能使用模板)<可以分配代码>标准::数组

  • 通过访问超出数组边界的元素,您将触发未定义的行为<代码> STD::数组:在将预成型边界检查,如果检查失败,则抛出常规C++异常。
  • 更好的可读性:内置数组包含指针和算术运算
    std::array
    实现了一些有用的函数,如
    front
    back
    begin
    end
    ,以避免出现这种情况

  • 假设我想对内置数组进行排序,代码可能如下所示:

    int arr[7] = {/*...*/};
    std::sort(arr, arr+7);
    
    这不是有史以来最健壮的代码。通过将
    7
    更改为不同的数字,代码将中断

    使用
    std::array

    std::array<int,7> arr{/*...*/};
    std::sort(arr.begin(), arr.end());
    
    std::数组arr{/*…*/};
    排序(arr.begin(),arr.end());
    
    代码更加健壮和灵活


    为了清楚起见,内置阵列有时会更容易。例如,许多Windows和UNIX API函数/系统调用都需要一些(小)缓冲区来填充数据。我不会使用
    std::array
    的开销,而是使用一个简单的
    char[MAX\u PATH]

    内置数组的唯一好处是声明语法更加简洁。但是
    std::array
    的功能优势将其抛诸脑后。 我还要补充一点,这真的没那么重要。如果您必须支持较旧的编译器,那么您当然别无选择,因为
    std::array
    仅适用于C++11。否则,您可以使用任何您喜欢的方法,但除非您只对数组进行微不足道的使用,否则您应该更喜欢std::array,以便与其他STL容器保持一致(例如,如果您以后决定将大小设置为动态,并改用std::vector,那么您将很高兴使用
    std::array
    ,因为您需要更改的可能只是数组声明本身,其余部分将是相同的,尤其是如果您使用C++11的自动和其他类型推断功能

    std::array
    是一个模板类,它封装了一个静态大小的数组,存储在对象本身内部,这意味着,如果在堆栈上实例化该类,数组本身将在堆栈上。它的大小必须在编译时已知(它作为模板参数传递),并且不能增长或收缩

    数组用于存储一系列对象 查看教程:

    一个std::vector也有同样的功能,但它比内置数组更好(例如:一般来说,vector有
    vector<vector<double>> G1=connectivity( current_combination,M,q2+1,P );
    vector<vector<double>> G2=connectivity( circshift_1_dexia(current_combination),M,q1+1,P );
    
    int n; std::cin >> n;
    int array[n]; // ill-formed but often accepted
    
    void foo(int array[])
    {
        // iterate over the elements
        for (int i = 0; i < sizeof(array); ++i)
             array[i] = 0;
    }