Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Листинг 6.1






#include < iostream.h>

#include < iomanip.h>

void main()

{

const int nrow = 10, ncol = 20;

int a[nrow][ncol];

int i, j;

setlocale(LC_ALL, " Russian");

 

cout < < “Введите элементы массива: ” < < endl;

 

for (i = 0; i < nrow; i++)

for (j = 0; j < ncol; j++) cin > > a[i][j];

 

for (i = 0; i < nrow; i++)

{

for (j= 0; j < ncol; j++) cout < < setw(4) < < a[i][j] < < “ ” cout < < endl;

}

 

int n_pos_el;

float s = 0;

 

for (i = 0; i < nrow; i++)

{

n_pos_el = 0;

 

for (j = 0; j < ncol; j++)

{

s += a[i][j];

if (a[i][j] > 0) n_pos_el++;

}

cout < < “Строка: ”< < i < < “количество: ” < < n_pos_el < < endl;

}

 

s /= nrow * ncol;

cout < < “Среднее арифметическое: ” < < s < < endl;

}

Размерности массива заданы именованными константами, что позволяет легко их изменять. Для упрощения отладки рекомендуется задать небольшие значения этих величин или приготовить тестовый массив в текстовом файле и изменить програм­му так, чтобы она читала значения из файла.

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

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

Здесь следует обратить внимание на два момента. Во-первых, требу­ется еще до написания алгоритма решить, каким образом будут храниться результаты. Для хранения среднего арифметического необходима одна простая переменная вещественного типа. Количество же положительных эле­ментов для каждой строки свое, и в результате получается столько зна­чений, сколько строк в матрице. В данном примере мы можно отвести для хранения этих значений одну-единственную переменную целого типа, поскольку они вы­числяются последовательно, после чего выводятся на экран. Однако в других за­дачах эти значения могут впоследствии потребоваться одновременно. В этом случае для их хранения придется описать целочисленный массив с количеством элемен­тов, равным количеству строк матрицы.

Второй важный момент - место инициализации суммы и количества. Сумма об­нуляется перед циклом просмотра всей матрицы, а количество положительных элементов - перед циклом просмотра очередной строки, поскольку для каждой строки его вычисление начинается заново.

Следует записывать операторы инициализации накапливаемых в цикле величин непосредственно перед циклом, в котором они вычисляются.

При написании вложенных циклов необходимо следить за отступами. Все операторы одного уровня вложенности должны начинаться в одной и той же колонке. Это облегчает чтение программы и, следовательно, поиск ошибок. По вопросу расстановки фи­гурных скобок существуют разные мнения специалистов. В настоящее время наи­более распространенными являются два стиля: стиль 1TBS (One True Bracing Style), которого придерживались основоположники языка С - Б. Керниган (Brian Kerni-ghan) и Д. Ритчи (Dennis Ritchie), и стиль Алмена (Eric Allman).

Динамические массивы. В динамической области памяти можно создавать двумерные массивы с помощью операции new или функции malloc. Остановимся на первом варианте, поскольку он более безопасен и прост в использовании.

При выделении памяти сразу под весь массив количество строк (самую левую раз­мерность) можно задавать с помощью переменной или выражения, а количество столбцов должно быть константным выражением, то есть явно определено до вы­полнения программы. После слова new записывается тип создаваемого массива, а за­тем - его размерности в квадратных скобках (аналогично описанию «обычных», нединамических массивов), например:

int n;

const int m = 5;

cin > > n;

int (*a)[m] = new int [n][m]; //1

int ** b = (int **) new int [n][m]; //2

В этом фрагменте показано два способа создания динамического массива. В опе­раторе 1 адрес начала выделенного с помощью new участка памяти присваивается переменной а, определенной как указатель на массив из m элементов типа int. Имен­но такой тип значения возвращает в данном случае операция new. Скобки необхо­димы, поскольку без них конструкция интерпретировалась бы как массив указате­лей. Всего выделяется n элементов.

В операторе 2 адрес начала выделенного участка памяти присваивается перемен­ной b которая описана как «указатель на указатель на int, поэтому перед присва­иванием требуется выполнить преобразование типа.

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

int ** b = reinterpret_cast < int-**> (new int [n][m]);

Обращение к элементам динамических массивов производится точно так же, как к элементам «обычных», с помощью конструкции вида a[i ][ j].

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

Более универсальный и безопасный способ выделения памяти под двумерный массив, когда обе его размерности задаются на этапе выполнения программы, при­веден ниже:

int nrow, ncol;

setlocale(LC_ALL, " Russian");

cout < < “Введите количество строк и столбцов: ”;

cin > > nrow > > ncol;

int **a = new int *[nrow]; //1

for(int i = 0; i < nrow; i++) //2

a[i] = new int [ncol]; //3

 

В операторе 1 объявляется переменная типа «указатель на указатель на i nt» и вы­деляется память под массив указателей на строки массива (количество строк - nrow). В операторе 2 организуется цикл для выделения памяти под каждую строку массива. В операторе 3 каждому элементу массива указателей на строки присваи­вается адрес начала участка памяти, выделенного под строку двумерного массива. Каждая строка состоит из ncol элементов типа int (рисунок 6.2).

int **a int *a[nrow] int a[nrow][ncol]

           
     
 
 
 
     
 
     
 


 

 


 

nstb

Рисунок 6.2 - Схема динамической области памяти, выделяемой под массивы

 

Освобождение памяти из-под массива с любым количеством измерений выполняется с по­мощью операции delete [].






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.