double **a;
// Выделили память
a = (double **)malloc(N*sizeof(double *));
for (int i = 0; i < N; i++) a[i] = (double *)malloc(M*sizeof(double));
// Заполнили массив какими-нибудь значениями
...
// Работаем с ним
WorkWithArray(a);
void WorkWithArray(double **a) {
fprintf(h, "%lf", a[1][2]);
}
Вопрос: откуда компилятор знает где брать a[1][2], ведь массив выделен динамически? Неужели он рюхает что в массиве N столбцов?
double **a;
fprintf(h, "%lf", aa[1][2]);
Почему вообще компилируется такой код? К какому элементу будет идти обращение, если размер строки нигде не определен?
После всех этих вопросов понял что я совсем дурак и полез в КР.
Там пишут:
Если двумерный массив передается функции в качестве аргумента, то объявление соответствующего ему параметра должно содержать количество столбцов ... в качестве примера дают
f(int daytab[][13]) { ... }
Иттить, а как же тогда работает WorkWithArray(double **a) ?
Здравствуйте, unz0r, Вы писали:
U>double **a;
U>fprintf(h, "%lf", aa[1][2]);
U>Почему вообще компилируется такой код? К какому элементу будет идти обращение, если размер строки нигде не определен?
Да просто тут всё. Это не массив массивов, как в случае
double v[N][M];
а массив указателей.
Для начала стоит разобраться с
double vv[N];
double *a = v;
Понимаешь ли ты в чём разница между v и a? И в чём между v[5] и a[5]?
Предположим, чо понимаешь. Тогда, наверное, легко поймёшь и двумерный случай.
double vv[N][M];
double **a;
В одном случае (когда массив массивов) vv[1] имеет тип double[M], а во втором случае (когда указатель на указатель) aa[1] имеет тип double*.
Короче говоря, в случае двумерного массива мы указатель на строку вычисляем, а в случае двойного указателя, мы указатели на строки храним. Не так компактно, конечно, зато быстро и можно выделять динамически
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Короче говоря, в случае двумерного массива мы указатель на строку вычисляем, а в случае двойного указателя, мы указатели на строки храним. Не так компактно, конечно, зато быстро и можно выделять динамически
Все понял. Спасибо огромное!
int main()
{
int v[2][2] = { 2, 3, 5, 7};
std::cout << 0[1[v]] << '\n';
}
Дело в том, что оператор [] всего лишь выполняет простую операцию. x[y] то же самое, что и *(x+y)