在此代码中使用const

using const in this code

本文关键字:const 代码      更新时间:2023-10-16

此代码在不使用const的情况下编译并执行良好。在这里使用const有什么特殊的原因吗?

0   #include <iostream>
1   using namespace std;
2
3   int sum(const int array[], const int length) {
4     long sum = 0;
5     for(int i = 0; i < length; sum += array[i++]);
6     return sum;
7   }
8
9   int main() {
10    int arr[] = {1, 2, 3, 4, 5, 6, 7};
11    cout << "Sum: " << sum(arr, 7) << endl;
12    return 0;
13  }
  • 代码参考:麻省理工学院C++公开课讲义4"数组和字符串"
  • 网址:http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-096-introduction-to-c-january-iap-2011/lecture-notes/MIT6_096IAP11_lec04.pdf

您使用const来实现const的正确性。这意味着你已经告诉编译器(以及你代码的任何读者)所有本身或他们工作的对象中没有改变的东西。你已经sum的args做了这件事,正确地说它们在函数中没有改变。你之所以这么做,是因为它掩盖了代码更容易推理(对读者来说),并打开了优化的可能性(对编译器来说)。

第一个常量背后有很多目的,而不需要第二个常量。

它将在没有const的情况下编译,但尝试以下函数:

int inc(const int array[], const int length) 
{
    for(int i = 0; i < length; ++i)
       ++array[i];
}

并且您的代码不应该编译。

移除第一个const,它会。

这向您展示了第一个const的用途。承诺不会更改数据。

相反,尝试更改调用函数:

int main() 
{
   const int arr[] = {1, 2, 3, 4, 5, 6, 7};
   cout << "Sum: " << sum(arr, 7) << endl;
   return 0;
}

现在,如果您尝试在不使用第一个const的情况下编译sum(),则会出现编译器错误,因为您无法将arr转换为非常量数组(本质上是指针)。

然而,即使7是一个常量,您仍然可以删除函数sum中的第二个常量,因为它是按值传递的。

int sum(const int array[], const int length) {/* ... */}

虽然第一个const不是顶级的(array是指向const int的不合格指针类型),但第二个是.

因此,第二个与函数定义相关,它根本不会更改功能声明,因此应作为外来噪声排除在纯声明之外。

等价声明

int sum(const int* array, int length); // Removed synatactic sugar and useless const
int sum(const int* const array, const int length); // Added top-level const

在第一部分的基础上,两个const的原因完全不同:

  • const限定length的原因与任何局部变量的原因完全相同:通过直接更改或不经意地将其传递给修改函数来避免不经意的更改
  • const限定指针array的元素类型(用于澄清它是一个数组的数组表示法)的原因是向调用方保证元素不会更改。这允许将指针传递到符合const条件和不符合int条件的两个
函数声明中有两个限定符const
int sum(const int array[], const int length);

事实上,第二个常量限定符对于使用函数没有任何特殊意义。这两个函数声明

int sum(const int array[], const int length);
int sum(const int array[], int length);

声明同一个函数。此常量仅在函数体中发挥作用。

对于第一个常量限定符,它允许将常量数组与此函数一起使用。例如,考虑使用以下数组定义的代码

const int arr[] = {1, 2, 3, 4, 5, 6, 7};

第一个const承诺永远不会更改数组。对于你发布的代码来说,这没有什么区别。但是假设arrmain中被声明为int const arr[]。编写的函数仍然可以工作,但如果没有const,它就不会工作,尽管从未更改过数组。

然而,length之前的const并没有改变函数的接口。它只是导致局部参数变量length不可更改。如果您确实不想在实现中更改length(因为编译器会将length的任何更改标记为错误),这可能是一种保护措施。