В объявлении функции, что означает передача массива фиксированного размера?

Это похоже на действительно глупую вещь, о которой нужно спросить, но у меня был кто-то, кто занимался программированием, попросил меня о какой-то помощи по заданию, и я вижу это в своем коде (без комментариев по венгерской нотации):

void read_dictionary( string ar_dictionary[25], int & dictionary_size ) {...

Что, в основном программист на С# (я узнал о C и С++ в колледже), я даже не знал, что вы могли бы сделать. Мне всегда говорили и читали, так как вы должны иметь

void read_dictionary( string ar_dictionary[], int ar_dictionary_size, int & dictionary_size ) {...

Мне сказали, что профессор дал им это и что он работает, и что означает объявление такого массива фиксированного размера, как это? У С++ нет собственного способа узнать размер передаваемого массива (даже если я думаю, что это могло быть изменено в новейшей спецификации)

Ответ 1

В одномерном массиве он не имеет значения и игнорируется компилятором. В двухмерном массиве Может быть полезно и используется функцией как способ определения длины строки матрицы (или многомерного массива). например:

int 2dArr(int arr[][10]){
   return arr[1][2];
}

эта функция будет знать адрес arr[1][2] в соответствии с указанной длиной, а также компилятор не должен принимать разные размеры массивов для этой функции -

int arr[30][30];
2dArr(arr);

не допускается и будет ошибкой компилятора (g++):

error: cannot convert int (*)[30] to int (*)[10]

Ответ 2

25 в объявлении параметра игнорируется компилятором. Это так же, как если бы вы написали string ar_dictionary[]. Это связано с тем, что объявление параметра типа массива неявно настраивается на указатель на тип элемента.

Итак, следующие три объявления функций эквивалентны:

void read_dictionary(string ar_dictionary[25], int& dictionary_size)
void read_dictionary(string ar_dictionary[],   int& dictionary_size)
void read_dictionary(string *ar_dictionary,    int& dictionary_size)

Даже в случае первой функции, размер массива, явно объявленный, sizeof(ar_dictionary) будет возвращать то же значение, что и sizeof(void*).

См. этот пример на Codepad:

#include <string>
#include <iostream>

using namespace std;

void read_dictionary(string ar_dictionary[25], int& dictionary_size)
{
    cout << sizeof(ar_dictionary) << endl;  
    cout << sizeof(void*) << endl;  
}

int main()
{
    string test[25];
    int dictionary_size = 25;
    read_dictionary(test, dictionary_size);

    return 0;
}

Выход (точное значение, конечно, зависит от реализации, это чисто для примера):

4
4

Ответ 3

Я всегда, хотя проходящие массивы С++ с фиксированным размером были "наполовину испеченными" функциями С++. Например, игнорируется сопоставление размеров или только возможность указать первый размер индекса и т.д. До недавнего времени я изучаю эту идиому:

template<size_t N1, size_t N2> // enable_if magic can be added as well
function(double(&m)[N1][N2]){
  ... do something with array m...knowing its size!
}

Ссылка: Может ли кто-нибудь объяснить этот код шаблона, который дает мне размер массива?