- •Н. А. Аленский основы программирования
- •§ 1. Структура простой программы. Ввод, вывод
- •1.1. Пример первой программы
- •1.2. Директива препроцессора #include
- •1.3. Структура программы
- •1.4. Комментарии
- •1.5. Ключевые слова и идентификаторы
- •1.6. Простой ввод, вывод
- •§ 2. Оператор if
- •2.1. Полная форма
- •2.2. Сокращённая форма
- •2.3. Особенности оператора
- •Задачи и упражнения
- •§ 3. Выражения
- •3.1. Константы
- •Непосредственно записать в выражении;
- •3.2. Операции и их приоритет
- •3.3. Операции отношения и логические операции
- •3.4. Особенности операции присваивания
- •3.5. Тернарная операция (?)
- •Задачи и упражнения
- •§ 4. Оператор выбора switch
- •Задачи и упражнения
- •§ 5. Операторы цикла
- •5.1. Оператор while c предусловием
- •Правила использования и особенности оператора while
- •5.2. Оператор цикла do … while c постусловием
- •5.3. Оператор for
- •5.4. Операторы continue и break
- •Задачи и упражнения
- •§ 6. Введение в одномерные массивы
- •6.1. Что такое массив. Объявление одномерного массива
- •6.2. Способы определения массивов
- •6.3. Вывод одномерного массива. Функции printf и сprintf
- •6.4. Некоторые типы простых задач при работе с массивами
- •Задачи и упражнения
- •§ 1. Функции без результатов. Передача параметров по значению
- •1.1. Примеры. Правила оформления и вызова функций
- •Void line2(int Len, y, char ch) // ошибка,
- •1.2. Формальные и фактические параметры
- •1.3. Передача параметров по значению
- •§ 2. Функции типа void с несколькими результатами
- •2.1. Пример
- •2.2. Что такое ссылочный тип
- •2.3. Возврат значений из функции с помощью ссылочного типа
- •Задачи и упражнения
- •§ 3. Функции с одним результатом. Оператор return
- •Задачи и упражнения
- •§ 4. Одномерные массивы в функциях. Сортировка массива
- •Задачи и упражнения.
- •§ 5. Область действия имён. Локальные и глобальные имена
- •§ 6. Дополнительные возможности функций
- •Встраиваемые функции (inlineфункции)
- •6.2. Параметры по умолчанию
- •6.3. Перегрузка функций
- •§ 1. Примеры
- •§ 2. Класс. Поля и методы класса
- •§ 3. Создание объектов. Конструктор
- •Задачи и упражнения.
- •Глава 4 простые типы данных § 1. Целый тип
- •1.1. Битовые операции
- •1.2. Использование битовых операций
- •1.3. Упаковка и распаковка информации
- •Задачи и упражнения.
- •§ 2. Логический тип
- •§ 3. Символьный тип
- •Глава 5 матрицы (двухмерные массивы) § 1. Объявление, способы определения
- •§ 2. Вывод матриц
- •§ 3. Типы алгоритмов на обработку матриц
- •3.1. Построчная обработка
- •3.2. Обработка матрицы по столбцам
- •3.3. Обработка всей матрицы
- •3.4. Обработка части матрицы
- •3.5. Преобразование матрицы
- •Упражнения.
- •3.6. Построение матриц
- •§ 4. Передача матрицы в качестве параметра функции
- •Задачи и упражнения.
- •Б. Обработка матрицы по столбцам.
- •Даны две матрицы a и b одинаковой размерности. Построить матрицу с, каждый элемент которой определяется по правилу:
- •Список рекомендуемой литературы
- •Сборники задач по программированию
- •Оглавление
- •Задачи и упражнения …….……………………………………...12
- •3.1. Константы ………………………………………………...…14
§ 4. Передача матрицы в качестве параметра функции
Здесь рассматривается этот вопрос без явного использования указателей.
Сначала рассмотрим передачу матрицы в качестве параметра самостоятельной функции без использования класса.
Независимо от того, является ли матрица входной для функции, получается в ней или одновременно входной и выходной, т. е. передаётся в функцию, преобразуется в ней и возвращается в точку вызова, правила передачи двумерного массива в качестве параметра функции одинаковы.
Есть два варианта объявления матрицы в скобках в заголовке функции:
-
c помощью явных или предварительно объявленных констант указываем обе размерности: void FunMatr1(…, int M[5][10], int size1,…). В этом варианте обрабатываем либо все (у нас 5) строки, либо меньшее их количество, которое можно, но не обязательно, передать через параметр (size1);
-
первую левую размерность можно оставить свободной, т. е. вместо количества строк оставляем пустые скобки. При этом количество столбцов обязательно надо записать: void FunMatr1(…, int M[][10], int size1…). В этом способе, как правило, передаётся в качестве параметра и количество строк (size1), которое используется в соответствующих циклах.
Нельзя оставить свободными обе размерности или одну вторую правую размерность. В таком случае непонятно, где заканчивается предыдущая строка и начинается следующая.
В обоих вариантах в функции необязательно обрабатывать указанное количество столбцов (у нас 10). Его, как и первую размерность, можно также передать в качестве параметра и затем использовать в теле функции:
void FunMatr2(…, int M[][10], int size1, int size2…);
В вызываемой функции (у нас в main) объявляем матрицу int A[5][10], учитывая следующее ограничение: количество столбцов при объявлении должно быть точно таким, как и в заголовке функции. Количество строк может быть меньше, чем в заголовке, например, int A[3][10]. При этом обрабатываться будут три строки (а не пять). При вызове функции в любом случае указываем только имя матрицы без указания размерности и типа её элементов, реальное количество строк и, если надо, столбцов: FunMatr1(…, A, 5, …); или FunMatr2(…, A, 3, 6, …); где 5 и 3 — количество обрабатываемых строк, 6 — количество обрабатываемых столбцов.
Пример. Составим функции для ввода, вывода матрицы и сортировки строк по элементам k –го столбца, где k передаём как параметр функции. При этом содержимое каждой строки не меняется.
const int n2=3;
void INP1(double x[][n2] , int );
void OUT1(double x[][n2], int );
void SORT1(double x[][n2], int , int );
int main()
{ const int size=5; int k;
double a[size][n2]; INP1(a,size);
cout<<"\nOld matrix\n"; OUT1(a,size);
cout <<"\nInput the number of collumn for sorting =>";
while(1) // Ввод номера столбца с проверкой правильности ввода
{ cin>>k;
if (k>=0 && k<n2) break;
cout<<"k>=0 && k<"<<n2<<" Repeat ";
}
SORT1(a,size,k); cout<<"\nMatrix after sorting\n"; OUT1(a,size);
getch(); return 0;
}
void SORT1(double x[][n2], int n, int k)
{ int i,j,m,mn,N;
for (m=0;m<n-1;m++)
{ mn=x[m][k]; N=m;
/* Поиск в k–м столбце минимального элемента, начиная с m–го (mn), и его номера(N).*/
for (i=m+1;i<n;i++)
if (x[i][k]<mn) { mn=x[i][k]; N=i;
}
// Перестановка m–й и N–й строк.
for(j=0;j<n2;j++)
{ double t; t=x[m][j];
x[m][j]=x[N][j]; x[N][j]=t;
}
}
}
void OUT1(double x[][n2], int n)
{ int X,j,Y=wherey();
for (int i=0; i<n; i++, Y++)
for (X=1, j=0; j<n2; j++, X+=7)
{ gotoxy(X,Y); cout<<x[i][j];
}
cout<<endl;
}
void INP1(double x[][n2],int n)
{ for (int i=0; i<n; i++)
for (int j=0; j<n2; j++)
x[i][j]=random(20)-10; }
При работе с матрицей в методах класса необходимо руководствоваться следующими правилами и рекомендациями.
Матрица объявляется в классе в качестве поля с максимальными первой и второй размерностями, в качестве которых можно использовать глобальные константы. Реальное количество строк и столбцов также объявляем, как два поля класса, и определяем их с помощью конструктора. Желательно в нём предусмотреть проверку, не превосходят ли реальные размерности матриц их наибольшие значения.
В методах класса матрица и её размерности в качестве параметров не записываются. Значения элементов матрицы определяются в каком–нибудь из методов класса одним из описанных в § 1 способов.
Для использования методов такого класса создаём объект.
Ту же задачу, что и в предыдущем примере, решим с помощью функций класса:
const unsigned n1max=5, n2max=10;
class MatrClass
{ double x[n1max][n2max]; unsigned size1, size2;
public:
MatrClass (unsigned n1, unsigned n2)
{ if (n1<=0 || n1>n1max) n1=n1max;
if (n2<=0 || n2>n2max) n2=n2max;
size1=n1; size2=n2;
}
void INP1( );
/* Поля класса (матрицу и её две размерности) в качестве параметров методов не записываем! Размерности передаём с помощью конструктора, а матрицу получаем с помощью метода INP1.*/
void OUT1( );
void SORT1( int );
} ;
void MatrClass::INP1()
{ for (int i=0; i<size1; i++)
for (int j=0; j<size2; j++)
x[i][j]=random(20)-10;
}
void MatrClass::SORT1(int k)
{ int i,j,m,mn,N;
for (m=0;m<size1-1;m++)
{ mn=x[m][k]; N=m;
for (i=m+1;i<size1;i++)
if (x[i][k]<mn)
{ mn=x[i][k]; N=i;
}
for(j=0;j<size2;j++)
{ double t; t=x[m][j];
x[m][j]=x[N][j]; x[N][j]=t;
}
}
}
void MatrClass::OUT1()
{ int X,j,Y=wherey();
for (int i=0; i<size1; i++, Y++)
for (X=1, j=0; j<size2; j++, X+=7)
{ gotoxy(X,Y);
cout<<x[i][j];
}
cout<<endl;
}
int main()
{ const int N1=3, N2=6; int k;
MatrClass ObjMatr ( N1, N2);
ObjMatr.INP1(); cout<<"\nOld matrix\n";
ObjMatr.OUT1();
cout <<"\nInput the number of collumn for sorting =>";
//Ввод номера столбца, по которому будем сортировать,
//с контролем ввода
while(1)
{ cin>>k;
if (k>=0 && k<N2) break;
cout<<"k>=0 && k<"<<N2<<" Repeat ";
}
ObjMatr.SORT1(k);
cout<<"\nMatrix after sorting\n";
ObjMatr.OUT1();
getch(); return 0;
}