Урок 9.4.6. Массивы в качестве аргументов

9.4.3. Массивы в качестве аргументов

При описании формальных параметров границы одномерных массивов можно опускать. Например,

int lengthfw(char buffer[], int size)
{ int i=0;
  while (i<size&&(buffer[i]!=' '))
  { i++;
  }
  return(i);
}

 

Функция lengthfw считает длину последовательности символов до первого пробела. При вызове функции для самого параметра-массива память не отводится, передаваемым значением является указатель на первый элемент массива. Правильный вызов для функции length: length(array, n);

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

void print_m(int a[][3], int n, int m);

Такое описание сообщает компилятору, что массив следует разбить на строки по три столбца, дополнительно передаются размерности массива.

Рассмотрим пример программы в которой вызывается функция print_m и её вариант функция print_s . Ей передается матрица и количество строк и столбцов на усмотрение программиста.

#include <conio.h>
#include <stdio.h>
#include <iostream.h>
void main()
{   
 void print_m(int a[][3], int n, int m);
 void print_s(int(*a)[3], int n, int m);
 int a[4][3]={ 1, 2, 3,
               4, 5, 6,
               7, 8, 9,
               0, 1, 2,
	  };
//во всех вызовах функции print_m ей передается 
//матрица a[4][3] 
print_m(a,4,3);
print_m(a,2,2);
print_m(a,5,4); //в данном случае функция выйдет 
                // за пределы матрицы
print_s(a,4,3);
 
getch();
}//End of main
 
/*функция print_m – вывод элементов массива
* параметры:
*  a – двумерный массив со строками из трех чисел
*  n – количество строк
*  m – количество столбцов.
* можно указать и такой заголовок функции:
* void print_m(int a[4][3], int n, int m) 
* первая размерность значения не имеет
*/
void print_m(int a[][3], int n, int m)
{
printf("Matrix\n");
for(int i = 0; i < n; i++)
   {
       for(int j = 0; j < m; j++)
          cout << a[i][j] << " ";
       cout << endl;
   }
} //End of print_m
 
/*функция print_s – вывод элементов массива
* параметры:
*  а - указатель на массив из 3 целых чисел
*  n – количество строк
*  m – количество столбцов.
*/
void print_s(int (*a)[3], int n, int m){
 printf("Matrix\n");
   	 for(int i = 0; i<n; i++)
    	 {
     		for(int j=0; j<m; j++)
        		cout << a[i][j]<< " ";
          	cout << endl;
    	 }
 
//другой вариант того же самого
printf("Matrix thru pointer\n");
    	for(int i = 0; i<n; i++)
    	{
      		for(int j=0; j<m; j++)
        		cout << *(a[i]+j)<< " ";
          	cout << endl;
   	 }
}//end of print_s

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

void print_m(int a[][13],int n, int m);

то получим сообщение, говорящее о несоответствии формального и фактического параметров:

Cannot convert 'int ( *)[3]' to 'int ( *)[13]'
Type mismatch in parameter 'a' in call to 'print_m (int(*) [13], int)'

Напоминаем, что количество строк может варьировать.

Как написать функцию, обрабатывающую двумерный массив с заранее не определенной длиной строки? В следующем примере рассмотрим фукции nummax1 и nummax2 ,  которые ищут максимальное число в любом двумерном массиве.

Фунции nummax1 передается указатель на первую строку массива (указатель на данные типа int) и далее функция работает с одномерным массивом. В этом случае все элементы массива должны располагаться в памяти друг за другом, из-за этого функция не сможет обработать динамический двумерный массив.

Фунции nummax2 передается указатель на на указатель на данные типа  int,  т.е. указатели на строки массива, поэтому для передачи массива в функцию формируется вспомогательный массив x. Эта функция может обработать как динамический, так и статический массив. Сформировать вспомогательный массив можно и в цикле. Делать это в этом примере мы не будем, но рассмотрим этот способ далее.

#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#include <iomanip.h>
int nummax1(int *a, int n, int m);
int nummax2(int **a, int n, int m);
//int nummax2(int *a[], int n, int m); //как вариант объявления
 
void main(){
int c[3][3]={ {-2, -54, 609},
	      {-4, 555, -89},
	      {14,   1, 657}
	    };
/*
Массив можно объявить и так:
int c[][3]={ {-2, -54, 609},
	     {-4, 555, -89},
	     {14,   1, 657}
	   };
*/
//создадим x – статический массив указателей на строки, чтобы
//в функции можно было работать с двумерным массивом
int* x[] = {c[0], c[1], c[2]};
 
int n = 3, m =3;
 
clrscr();
cout<<"Matrix: "<<endl;
for(int i = 0; i < n; i++){
   for(int j = 0; j < m; j++)
       cout << setw(4) << c[i][j];  //(*(*(i+i)+j)))
   cout<<endl;
}
 
cout << endl << "max number: " << nummax1(c[0], n, m) << endl;
cout << endl << "max number: " << nummax2(x, n, m) << endl;
 
getchar();
}
 
int nummax1(int *a, int n, int m){
// обрабатывается как одномерный массив, работает только
// для статического массива 
  int max;
  max = a[0];   //ili tak max = *a;
 
   for(int i = 0; i < n*m; i++)
      if( max < a[i]) max = a[i];
 
   // фрагмент аналогичный предыдущему
   for(int i = 0; i < n*m; i++)
     if( max < *(a+i)) max = *(a+i);
 
  return max;
}//end of nummax1
 
int nummax2(int **a, int n, int m){//a ¬– массив n на m
     int max;
  max = a[0][0];
  //можно и так: max = **a;
   for(int i = 0; i < n; i++)
      for(int j = 0; j < m; j++)
 	  if( max < a[i][j]) max = a[i][j];
 
  return max;
}//end of nummax2

Рассмотрим пример, в котором функцией createArray создается динамический массив, указатель на который возвращается в основную программу и передается затем в функцию randmass(), которая инициализирует его случайными значениями при помощи стандартной функции rand. Функция printArray выводит массив на экран.

Прочитать как инициализируются указатели и массивы можно в разделах 7.1.5. Инициализация указателей и 7.2.2. Инициализация массивов, там же есть и примеры освобождения памяти, занимаемой указателями и массивами.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
using namespace std;
void randmass(int **, int, int);
int nummax(int **, int, int );
int ** createArray(int n, int m);//создать двумерный массив
void printArray(int **, int n, int m);//печать массива
void freeArray(int **, int n);//освободить память,занимаемую массивом, n - количество строк
 
void main(){
 int **matrix;
 int n = 5; // число строк
 int m = 4; // число столбцов
 
//создаем динамический массив размерности n на m
matrix = createArray(n,m);
//инициализация массива в функции
randmass(matrix, n, m);
//вывод массива на экран
printArray(matrix, n, m);
//освободить память занимаемую массивом из n строк
freeArray(matrix, n); 
 
getchar();
}
 
//функция создания массива
int ** createArray(int n, int m)
{
    //динамический массив с заранее не определенной размерностью
    int **a = new int* [n];   
    for (int i = 0; i < n; i++)
        a[i]= new int[m];
    return a; //возвращаем указательна на массив
}
 
//функция инициализации массива
void randmass(int ** a, int rows, int cols)
{
    for (int i=0; i<rows; i++){
        for (int j=0; j<cols; j++){
            a[i][j] = rand() %100 - 5;  //stdlib.h
        }
    }
}
 
//функция вывода массива
void printArray(int **a, int n, int m)
{
   cout<<"Matrix: "<<endl;
   for(int i = 0; i < n; i++){
       for(int j = 0; j < m; j++)
           cout << setw(4) << a[i][j];
   cout<<endl;
   }
}
 
//функция освобождения памяти, занимаемой массивом
void freeArray(int **a, int n)
{
    for(int i = 0; i < n; i++)
        delete [] a[i];//вначале освободим память, отведённую собственно под матрицу
    delete [] a;//теперь освобождаем память, занятую массивом указателей
}

 

рассказать друзьям и получить подарок

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов