Читайте также:
|
|
Самый сложный случай - когда надо передавать обе размерности, то есть наша функция должна работать с массивом произвольной размерности. Здесь "очевидное" решение просто непригодно:
void print_arr(int m[][], int dim1, int dim2) // ошибка
{
for (int i = 0; i<dim1; i++)
{
for (int j = 0; j<dim2; j++)
cout << ' ' << m[i][j]; //*(*(m+i)+j) – компилятор не знает, на что нужно
//домножать i
cout << '\n';
}
}
Описание параметра как m[][] для компилятора недопустимо, поскольку ему для вычисления адреса элемента многомерного массива нужно знать вторую
Размерность. Для решения этой проблемы предлагается следующий подход. Память,
Занимаемая двухмерным массивом, интерпретируется как память, занимаемая
Одномерным массивом. Так как двухмерный массив в одномерной памяти
Располагается по строкам, то элементу двухмерного массива с индексами i и j,
соответствует элемент одномерного массива со значением индекса k=i*dim2+j. Значение к равняется количеству предшествующих элементов массива, а оно равно количеству элементов в предшествующих строках (i*dim2) плюс количество предшествующих элементов в текущей строке (j).
Поскольку в языке Си индексация начинается с 0, из i и j не требуется вычитать по единице. То есть мы проделываем те же вычисления, что и компилятор, когда он вычисляет смещение элемента многомерного массива относительно адреса начала этого массива.
Поэтому правильным решением будет:
#include <iostream.h>
void print_arr(int * array, int dim1, int dim2)
{
for (int i = 0; i< dim1; i++)
{
for (int j = 0; j<dim2; j++)
cout << ' ' << array[i*dim2+j];
cout << '\n';
}
}
Void main(void)
{
int m[3][3]= { 1,2,3,
4,5,6,
7,8,9};
print_arr((int*)m,3,3);
// или (почему это дает правильный результат??????)
print_arr(m[0],3,3);
print_arr(*m,3,3);
print_arr(&m[0][0],3,3);
print_arr(&**m,3,3);
Getch();
}
Функции overload (перезагружаемые)
Важным расширением, пришедшим из языка ADA, является то, что транслятор С различает функции не только по именам, но и по типу аргументов. Например, функцию
double sqr (double x) {return x*x;}
Можно дополнить функцией
int sqr(int x) {return x*x;}
Обе спокойно уживаются в одной программе. При вызове будет использована
нужная функция. Какая - решает тип аргумента. Как же это делается? Дело в том,
Что историческое название overload (перезагрузка) никакого отношения к действительности не имеет. Просто транслятор в своей работе использует внутренние имена функций, которые содержат в себе скрытое описание типов аргументов. С этими же именами работают программы компоновщика и библиотекаря. Данный механизм и позволяет программам иметь несколько функций с одинаковыми именами, но с разными типами аргументов. Замети, что транслятор не различает функции по типу возвращаемого значения.
Дата добавления: 2015-07-07; просмотров: 198 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Использование const при описании функции. | | | Параметры функции по умолчанию |