Для доступа к определенному элементу многомерного массива необходимо указать в квадратных скобках конкретные значения всех индексов этого элемента. Например:
cout << A1 [1] [2]; // На экран выведено значение 8
6.3. Ввод-вывод массивов
Ранее были рассмотрены приемы ввода-вывода простых предопределенных типов данных (int, double, char и bool) с помощью потоков ввода и вывода. Стандартные потоки ввода и вывода не “умеют” работать с массивами, поэтому ввод и вывод массивов необходимо реализовывать самостоятельно, обрабатывая массивы поэлементно.
Большинство алгоритмов по обработке массивов реализуются с помощью циклов. Ввод и вывод массивов не являются исключением.
Начнем с рассмотрения операций вывода значений элементов массивов на экран.
// Для использования setw() необходимо включить #include <iomanip>
for (int i = 0; i < n; ++i)
cout << setw(8) << left << A[i];
cout << endl;
На каждом шаге этого цикла в поток вывода отправляется очередной i-й элемент массива, при этом устанавливается ширина поля вывода, равная 8 позициям, выравнивание по левому краю. После окончания цикла вывода всех n элементов массива осуществляется переход на следующую строку экрана.
Обратим внимание на то, что в программах выгоднее задавать размеры массивов через именованные константы (в данном примере – константа n), для того чтобы использовать эти же константы для управления работой циклов. При необходимости изменить размеры массива достаточно будет поменять значение этой константы. При этом все циклы, использующие для управления своей работой эту константу, автоматически приспособятся к изменившимся размерам обрабатываемого массива.
Вывод двумерных массивов, как правило, осуществляется в табличной форме. Реализация такого алгоритма может быть, например, такой:
const int n = 10, m = 10;
short A [n] [m];
…
for (int i = 0; i < n; ++i)
// Выводим i-ю строку массива
{
for (int j = 0; j < m; ++j)
// Выводим j-й элемент i-й строки массива
cout << setw(7) << right << A [i] [j];
cout << endl;
}
Здесь используются вложенные циклы. Обратите внимание, что внутренний (вложенный) цикл практически идентичен циклу, реализующему вывод элементов одномерного массива.
6.4. Текстовые строки как массивы символов
6.5. Массивы и указатели
7. Разработка программ при работе с массивами
Картинки массивов при записи предусловий, постусловий и инвариантов. Примеры: задачи разделения и слияния массивов, перестановка сегментов массива (циклический сдвиг) и т.п. Линейный и бинарный поиск в массиве. Оптимальность алгоритмов поиска. Оптимизация программ. Простые алгоритмы сортировки (выбором, вставками, обменами). Работа с двумерными и многомерными массивами.
8. Функции и структура программы
Создание и использование функций. Вызов функции (аргументы функции) и возврат значения. Передача параметров по значению, по ссылке. Глобальные и локальные переменные. Классы памяти и область действия. Автоматические переменные. Внешние переменные. Статические переменные. Внешние статические переменные. Регистровые переменные. Указатели. Функции с переменным количеством аргументов. Представление программы в виде набора функций. Многофайловая структура программы. Использование функции как параметра другой функции; пример применения - итерационные методы решения нелинейных уравнений.
9. Организация ввода/вывода и работа с файлами
Последовательность (как модель файла) и файл. Потоки и работа с файлами. Базовые операции с файлами. Типовые действия с файлами: генерация, чтение, копирование. Форматирование ввода и вывода. Схема однопроходных алгоритмов обработки файлов (вычисление функций на последовательностях). Примеры.
Заключение
Основные тенденции и направления развития методов и языков программирования. Связь с учебной дисциплиной по программированию (дополнительные главы) следующего семестра.
Приложение. Некоторые полезные примеры и иллюстрации к разделам конспекта
Все программы, приведенные в этом разделе, реализованы в среде MS Visual C++ 2010.
Примеры к разделу 5
Вычисление факториала числа
// Факториал.cpp: определяет точку входа для консольного приложения.
// Различные реализации функций для вычисления факториала числа
#include "stdafx.h"
#include <iostream>
#include <iomanip> // для манипулятора setw()
#include <limits.h> // для ULONG_MAX - максимальное значение типа unsigned long
using namespace std;
unsigned Factorial_Err(unsigned n)
// При n > 12 значение n! превышает максимальное значение ULONG_MAX типа unsigned
// и функция возвращает неправильные значения
{
unsigned i = 0; // Текущее значение i
unsigned F = 1; // Текущее значение i!
while (i < n)
{
++ i; // i = i + 1
F *= i; // F = F * i - Текущее значение i!
}
return F; // Возвращаем значение n!
}
unsigned Factorial(unsigned n)
// При переполнении возвращает 0 с сообщением об ошибке
// Реализация с помощью цикла while
{
unsigned i = 0; // Текущее значение i
unsigned F = 1; // Текущее значение i!
while (i < n)
{
++ i; // i = i + 1
if (ULONG_MAX / i < F)
{
F = 0;
cout << "Ошибка. При вычислении n! максимальное "
"значение n не может превышать " << --i << endl;
break;
}
F *= i; // F = F * i - Текущее значение i!
}
return F; // Возвращаем значение n!
}
unsigned Factorial_1(unsigned n)
// При переполнении возвращает 0 с сообщением об ошибке
// Реализация с помощью цикла for
{
unsigned F = 1; // Значение 0!
for (unsigned i = 1; i < n; ++i, F *= i)
if (ULONG_MAX / i < F)
{
F = 0;
cout << "Ошибка. При вычислении n! максимальное "
"значение n не может превышать " << --i << endl;
break;
}
return F; // Возвращаем значение n!
}
unsigned Factorial_2(unsigned n)
// При переполнении возвращает 0 без сообщения об ошибке
// Реализация с помощью цикла for
{
unsigned F = 1; // Значение 0!
for (unsigned i = 1; (i < n) && F; ++i, F = (ULONG_MAX / i < F) ? 0 : F * i);
return F; // Возвращаем значение n!
}
int main()
// Для проверки работы одного из вариантов необходимо
// снять комментарии с соответствующей строки цикла for
// и закомментировать остальные
{
for (int i = 0; i <= 13; ++ i)
{
cout << setw(2) << right << i << "! = " << Factorial_Err(i) << endl;
// cout << setw(2) << right << i << "! = " << Factorial(i) << endl;
// cout << setw(2) << right << i << "! = " << Factorial_1(i) << endl;
// cout << setw(2) << right << i << "! = " << Factorial_2(i) << endl;
}
system ("Pause");
return 0;
}
Быстрое возведение чисел в целую степень
// ЦелаяСтепень.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
double IntPow(double b, int k, int &Count)
{
// Инвариант: (b ^ k) * p = a ^ n
// Цикл заканчивается при k = 0, тогда p = a ^ n
double p = 1;
Count = 0;
while (k != 0)
{
if (k & 1) // k не четно
{
-- k; // k = k - 1
p *= b; // p = p * b
}
else
{
k /= 2; // k = k / 2
b *= b; // b = b * b
}
++ Count;
}
return p;
}
double IntPow1(double a, int n, int &Count)
{
double p = 1;
double b = a;
for (int i = n, Count = 0; i; (i % 2) ? (p *= b, --i) : (b *= b, i /= 2),
++ Count);
return p;
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(0, "");
cout << " Алгоритм быстрого возведения числа в целую степень.\n";