- •Void swap(int * arg1, int * arg2)
- •Void main(void)
- •Void swap(int & arg1, int & arg2)
- •Void main(void)
- •Int &move(int&I)
- •Void main(void)
- •Int& f() { return 1; } // ошибка
- •Void f(const large& arg)
- •Void g(large& arg); // считается, что в g() arg будет меняться
- •Void CorrArr(int * Arr, int Dim)
- •Void main(void)
- •Void print_arr(int m[3][4])
- •Void print_arr(int m[][4], int dim1)
- •Void print_arr(int m[][], int dim1, int dim2) // ошибка
- •Void print_arr(int * array, int dim1, int dim2)
- •Void main(void)
- •Int sqr(int X) {return X*X;}
- •Int printf(const char*, ...);
- •Void error(char* p) { /* ... */ }
- •Void (*efct)(char*); - указатель на функцию, которая ничего не возвращает и
- •Void f()
- •Void Sort(int Arr, int Dim, int(*Compare)(int, int))
- •Int Change, tmp;
- •If(!Change)
- •Void main(int argc, char * argv[])
- •Void main(int argc, char ** argv, char ** envp)
- •Void main(void)
- •Void main(int argc, char *argv[])
Void CorrArr(int * Arr, int Dim)
{
int i;
for(i=0;i<Dim;i++)
if(Arr[i]<1)
Arr[i]=0; //*(Arr+i)=0;
}
Void main(void)
{
int a[]={1,-2,-3,4};
CorrArr(a,4);
printf("%d %d\n",a[1],a[2}); //будет напечатано 0 0
}
Таким образом, массивы отличаются от других типов тем, что они не передаются и не могут передаваться по значению.
В вызываемой функции размер передаваемого массива неизвестен. Это неприятно, но есть несколько способов обойти данную трудность. Прежде всего, все строки заканчиваются нулевым символом, и значит их размер легко вычислить.
Можно передавать еще один параметр, задающий размер массива, как это было в вышеприведенном примере.
Сложнее обстоит дело с многомерными массивами. Рассмотрим функцию, работающую с двумерным массивом - матрицей.
Если размеры обоих индексов известны на этапе трансляции, то проблем нет:
Void print_arr(int m[3][4])
{
for (int i = 0; i<3; i++)
{
for (int j = 0; j<4; J++)
cout << ' ' << m[i][j];
cout << '\n';
}
}
Конечно, матрица по-прежнему передается как указатель, а размерности
используются компилятором для вычисления адреса элемента. Первая размерность
для вычисления адреса элемента не важна (почему??????), поэтому ее можно
передавать как параметр:
Void print_arr(int m[][4], int dim1)
{
for ( int i = 0; i<dim1; i++)
{
for ( int j = 0; j<4; j++)
cout << ' ' << m[i][j]; //*(*(m+i)+j) - j умножается на размер элемента,
//а он известен (размер int)
cout << '\n';
}
}
Данная функция может печатать содержимое двухмерных массивов с любой первой размерностью.
Самый сложный случай - когда надо передавать обе размерности, то есть наша функция должна работать с массивом произвольной размерности. Здесь "очевидное" решение просто непригодно:
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>
