этот код скомпилирован и выполнен без использования константы. Существует ли специальная причина использования 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 }
Вы используете const
для достижения const
-correctness. Это означает, что вы сказали компилятору (и любому читателю вашего кода) все вещи, которые не меняются сами по себе или объекты, над которыми они работают. Вы сделали это для арг на sum
, правильно говорят, что они не изменяются в функции. Причина, по которой вы это делаете, заключается в том, что он маскирует код, который легче рассуждать (для читателя), и открывает возможности оптимизации (для компилятора).
const int
. (Квалификаторы верхнего уровня аргументов функции не являются частью объявления функции, а являются только определением, смотрите length
. И в этом случае квалификаторы могут быть добавлены при присваивании аргументу)
За первым состязанием существует большая цель, нет реальной потребности в втором.
Он будет компилироваться без 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;
}
Теперь, если вы попытаетесь скомпилировать sum()
без первого const
вы получите ошибку компилятора, потому что вы не можете преобразовать 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
совершенно разные:
length
const
-qualifying такая же, как для любой локальной переменной: избегайте непреднамеренных изменений, напрямую меняя ее или непреднамеренно передавая ее модифицирующей функции.const
-qualifying является тип элемента array
указателей (обозначение массива, используемое для уточнения того, что оно предназначено как массив), гарантирует вызывающему, что элементы не будут изменены. Это позволяет передавать указатель на const
-qualified и un -qualified int
s.В объявлении функции есть два классификатора const
int sum(const int array[], const int length);
На самом деле второй определитель const не имеет особого значения для использования функции. Эти две объявления функций
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
обещает никогда не изменять массив. Для кода, который вы опубликовали, это не имеет значения. Но представьте, что arr
был объявлен main
как int const arr[]
. Функция, как написано, все равно будет работать, но без const
она не будет, несмотря на то, что она никогда не меняет массив.
const
до того length
, однако не изменяет интерфейс функции. Это просто приводит к тому, что переменная length
локального аргумента остается неизменной. Это может быть защитой, если вы действительно не хотите изменять length
в реализации (потому что компилятор будет отмечать любое изменение length
как ошибку).
const T xx[]
, спрашивается толькоconst T