Лекции по программированию

Автор: Пользователь скрыл имя, 17 Января 2011 в 18:57, курс лекций

Описание работы

6 тем.

Работа содержит 1 файл

Лекции.doc

— 615.00 Кб (Скачать)

    for ( int i =0; i <10; ++ i )

    a [ i ]= new int [5];

В этом случае мы получим  двумерный массив целых чисел, который  содержит 10 строк и 5 столбцов. В общем  случае вместо констант 10 и 5можно поставить  переменные и тогда получим массив необходимой размерности для  данной задачи. Кроме того, для каждого значения мы можем создавать одномерные массивы различной размерности. В результате у нас получится не прямоугольный массив, а свободный (количество элементов в каждой строке различно).

Обратиться к элементам  динамического массива можно  с помощью индексации, например, a[i][ j ] , или с помощью указателей *(*(a+i)+ j ) .

Рассмотрим более  подробно второе выражение. Указатель а хранит адрес указателя на нулевую строку. Операция a+i обратится к указателю на i-тую строку массива. Выражение *(a+i) позволит обратиться к значению, хранящемуся по адресу a+i – фактически к адресу нулевого столбца i-той строки двумерного массива. И, соответственно, выражение *(*(a+i)+ j ) позволит обратиться к значению j-того столбца i-той строки.

Оба выражения эквивалентны друг другу, однако первое более понятно, а второе более быстродейственно при выполнении программы, потомучто компилятор всегда переводит индексный способ обращения к массиву к обращению через указатели.

Ввод и вывод  массивов также как и в случае со статическими массивами производится поэлементно. В следующем фрагменте программы производится потоковой ввод и вывод целочисленного массива,который содержит 4 строки и 5 столбцов:

    int **b=new int *[4]; //объявили двумерный динамический массив

    for (int i=0; i<2; ++i) b[i]=new int [5];

    for (int i=0;i<4; ++i) // ввод элементов массива

    for (int j=0;j<5; ++j)

      cout <<" b ["<< i <<"]["<< j <<"]=";

      cin >>*(*( b + i )+j);//введенное значение записываем в b [i][ j ]

    }

    for (int i=0;i<4; ++i, cout<<endl) // вывод элементов массива

    for (int j=0;j<5; ++j)

    cout<<"b["<<i<<"]["<<j<<"]="<<*(*(b+i)+j)<< "\t"; // выводи на экран значение b[i][j]

Освободить память, выделенную под динамический массив можно с помощью операции delete. Например, освобождение памяти, выделенной под элементы массива из предыдущего примера, производится следующим образом:

    //освобождаем  память, выделенную  под i -тую строку двумерного массива

    for (int i=0;i<4; ++i) delete[] b[i];

    delete [] b ; // освобождаем  память, выделенную под массив указателей.

      Замечание. Данный фрагмент программы освобождает память, выделенную в куче под двумерный массив, сам указатель b при этом сохраняется и может повторно использоваться для определения другого массива. 

Передача  двумерных массивов в качестве параметров 

При использовании  в качестве параметра двумерного массива в функцию передается указатель на элемент, стоящий в  нулевой строке и нулевом столбце. Этим указателем является имя массива. Также как и в случае с одномерными  массивами операцию разадресации внутри функции при обращении к элементам массива выполнять не надо, т.к. запись вида a[i][ j ] автоматически заменяется компилятором на выражение *(*(a+i)+ j ).

При передаче двумерного массива в качестве параметра  функции информация о количестве строк и столбцов теряется, поэтому размерности массива следует передавать в качестве отдельных параметров. Рассмотрим несколько примеров:

1. Передача статического  массива:

    #include <iostream>

    using namespace std;

    /*в  функцию в качестве  параметров передаются  статический массив mas и его размерности: n – количество строк, m- количество столбцов*/

    void print (int mas[3][2], int n, int m)

    {

      for (int i=0; i<n; ++i, cout<<endl)

        for (int j=0; j<m; ++j) 

        cout<<mas[i][j]<<"\t";

    } 

    int main()

    {

      int a[3][2]={{1, -2}, {-3, 4}, {-5,6} };

      print(a,3,2); cout<<endl;

      print (a, 2,2)

      return 0;

    } 

Результат работы программы:

1 -2

-3 4

-5 6

1 -2

-3 4

      Замечание. При втором вызове функции print в качестве параметра мы передали значение меньше реального количества строк в массиве,поэтому мы смогли распечатать не весь массив, а его часть. Подумайте, что произойдет, если в качестве или передать значение большее реальной размерности массива.

2. Передача динамического  массива:

    #include <iostream>

    using namespace std;

    /*в  функцию в качестве параметров передаются динамический массив mas и его размерности: n – количество строк, m- количество столбцов*/

    void print (int **mas, int n,int m)

      for (int i=0; i<n; ++i, cout<<endl)

        for (int j=0; j<m; ++j)

        cout<<mas[i][j]<<"\t";

    }

    int main()

    {

      int n=3, m=4;

      int **a=new int *[n];

      for (int i=0; i<n; ++i) 

        a[i]=new int [m];

      for (int i=0; i<n; ++i)

        for (int j=0; j<m; ++j)

        a[i][j]=i+j;

      print(a,3,4);

      for (int i=0;i<n; ++ i) 

        delete [] a[i]; // освобождение памяти

      delete [] a;

      return 0;

    } 

Результат работы программы:

0 1 2 3

1 2 3 4

2 3 4 5 

Поскольку массив всегда передается в функцию поадресу, то все изменения, внесенные в формальный параметр массив, отразятся на фактическом  параметре массиве. Если необходимо запретить изменение массива  в функции, то его нужно передавать как параметр константу. Например:

    int sum ( const int ** mas , const int n )

    { … }

Напомним, что двумерный  массив – это одномерный массив указателей, каждый из который в  свою очередь ссылается на одномерный массив.Поэтому двумерный массив можно передавать во вспомогательную функцию для обработки построчно:

    #include <iostream>

    using namespace std;

    /*в  функцию в качестве  параметров передаются  одномерный массив mas и его размерность n */

    void print (int *mas, int n)

    {

      for (int i=0; i<n; ++i) 

        cout<<mas[i]<<"\t";

      cout<<endl; 

    } 

    int main()

    {

      int n=3, m=4;

      int **a=new int *[n];

      for (int i=0; i<n; ++i)

      a[i]=new int [m];

      for (int i=0; i<n; ++i)

      for (int j=0; j<m; ++j) a[i][j]=i+j;

      for ( int i =0; i < n ; ++ i ) // обработка двумерного массива построчно: в качестве аргумента

        print ( a[i], m ); / функции print передаем указатель на i-тую строку

      for (int i=0;i<n; ++ i) 

delete [] a[i]; // освобождение памяти

      delete [] a ;

      return 0;

    }

Замечание. Результат работы программы будет соответствовать предыдущему примеру. 

Двумерный массив как возвращаемое значение функции 

Двумерный массив может  возвращаться в качестве значения функции  только как указатель:

    #include <iostream>

    using namespace std;

    int ** create(int n, int m);

    {

      int **mas=new int *[n];

      for (int i=0; i<n; ++i) 

        mas[i]=new int [m];

      for (int i=0; i<n; ++i)

        for (int j=0; j<m; ++j)

        mas[i][j]=i+j;

      return mas;

    }

    int main()

    {

      int n=5, m=5; int **a=create(n,m);

      print(a,n,m);

      for (int i=0;i<n; ++ i) 

delete [] a[i]; // освобождение памяти

      delete [] a;

      return 0;

    } 

Результат работы программы:

0 1 2 3 4

1 2 3 4 5

2 3 4 5 6

3 4 5 6 7

4 5 6 7 8 

    6.6. Примеры использования двумерных массивов

Двумерные массивы  находят свое применение тогда, когда  исходные данные представлены в виде таблицы, или когда для хранения данных удобно использовать табличное представление. В данном разделе мы рассмотрим примеры использования двумерных массивов. При решении задач мы будем использовать динамические массивы, но обращаться к элементам через индексы.Однако вы можете обращаться к элементам массива и через указатели. Для этого нужно будет заменить выражение a[i][ j ] на *(*(a+i)+ j ).

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

Указания  по решению задачи. Массив результатов будет одномерный, а его размерность будет совпадать с количеством столбцов исходной матрицы.

    #include <iostream>

    using namespace std;

    int ** create(int &n, int &m)

      cout <<"n="; cin >>n; cout <<"m=";cin >>m;

      int **mas=new int *[n];

      for (int i=0; i<n; ++i)

        mas[i]=new int [m];

      for (int i=0; i<n; ++i)

      for (int j=0; j<m; ++j) 

      {

        cout<<"mas["<<i<<"]["<<j<<"]=";

        cin>>mas[i][j];

      }

      return mas;

    } 

    int main()

    {

      int n, m;

      int **a=create(n,m);

      float * b = new float [ m ]; //создание массива результатов

      for ( int j =0; j < m ; ++ j ) // для каждого j -го столбца

      {

        b [ j ]=0; 

        int k =0; //обнуляем сумму и количество нечетных элементов столбца

        for ( int i =0; i < n ; i ++) // перебираем все элементы j-того столбца и находим

        if ( a [ i ][ j ]%2) 

        {

        b [ j ]+= a [ i ][ j ];//сумму

        k ++; //и количество  нечетных элементов

        }

        if ( k ) //если количество нечетных элементов положительное, то

        b [ j ]/= k ; //то вычисляем среднее арифметическое

      }

      for ( int i =0; i < m ; i ++) //вывод массива результатов

      cout<<b[i]<<"\t";

      for (int i=0;i<n; i++) 

delete [] a[i];//удаление массива а

      delete [] a;

      delete [] b; //удаление массива b

      return 0;

    }

Результат работы программы

n=2

m=3

Массив  Аn´m Ответ
2 1 3

4 3 6

Вывод результата:0.002.003.00

Информация о работе Лекции по программированию