- •Лекция 1 Создание консольного приложения
- •2. Консоль. Построение консольного проекта
- •3. Запуск приложения
- •4. Сохранение и редактирование проекта
- •Лекция 2
- •4. Функции форматированного ввода и вывода
- •4.1. Функция форматированного ввода с клавиатуры
- •4.2. Функция форматированного вывода на экран
- •5. Математические функции
- •Лекция 3 Линейные вычислительные процессы
- •1. Алгоритм. Управляющие структуры
- •2. Линейные вычислительные алгоритмы
- •2.1. Условный оператор if()
- •2.2. Условное выражение
- •2.3. Оператор выбора switch()
- •Лекция 5 Программирование разветвляющихся вычислительных процессов
- •Лекция 6 Циклические вычислительные процессы.
- •1. Типы циклов
- •3. Операторы безусловного перехода
- •Лекция 7 Вычисление последовательностей
- •4. Примеры вычисления последовательностей
- •5. Структура алгоритмов вычисления рекуррентных последовательностей
- •Лекция 8 Одномерные массивы
- •1. Массивы
- •1.1. Примеры программ обработки одномерных массивов
- •1.2. Сортировка выбором
- •1.3. Сортировка простыми вставками
- •Лекция 10 Двухмерные массивы
- •1. Двухмерные массивы
- •Лекция 11 Алгоритмы матричной алгебры
- •1. Алгоритмы матричной алгебры
- •Лекция 12 Динамические массивы
- •1. Память компьютера. Адресное пространство
- •2. Динамическая память
- •3. Адреса и указатели
- •4. Указатели и массивы. Динамические массивы
- •5. Проблемы, связанные с указателями
- •6. Поразрядные операции
- •1.2. Способы объявления и обращения к элементам двухмерных массивов
- •Лекция 14 Символы и строки
- •1. Символьный тип данных
- •2. Строки
- •Лекция 15 Структуры
- •1. Понятие структуры
- •2. Определение нового имени типа
- •3. Массивы структур. Указатели на структуры
- •3.1. Определение статического массива структур
- •3.1. Определение динамического массива из n структур
- •Лекция 16 Файлы
- •1. Потоковый ввод-вывод данных
- •3. Понятие файла. Функции работы с файлами
- •Лекция 17 Файлы
- •Лекция 18 Функции пользователя
- •I. Приёмы построения алгоритмов
- •2. Понятие функции
- •2.1. Определение функции
- •2.2. Область видимости переменных
- •2.3. Параметры функции
- •2.4. Описание функции
- •2.5. Организация вызова функции
- •2.5. Передача параметров в функцию
- •3. Рекурсия
- •Лекция 20 Нахождение приближенного значения корня нелинейного уравнения
- •На отрезке [a;b] с заданной точностью eps
- •1.1. Метод дихотомии (половинного деления)
- •1.2. Метод хорд
- •1.3. Метод касательных (Ньютона)
- •Лекция 22 Объектно-ориентированное программирование
- •Полиморфизм – это свойство класса, позволяющее определить одно и то же по имени, но разное по смыслу действие. Основные этапы ооп:
- •Уточнённое имя принадлежит классу (т.Е. Компонентной) функции
- •Лекция 23 Объектно-ориентированное программирование
- •1. Конструкторы и деструкторы
- •1.2. Определение компонентных функций
- •Лекция 25 Объектно-ориентированное программирование
- •1. Свойства классов
- •1.1. Наследование классов
- •1.2. Полиморфизм
- •Библиографический список
1.2. Способы объявления и обращения к элементам двухмерных массивов
Рассмотрим объявление и связь указателей и элементов двухмерных массивов. Двухмерный массив в языке С++ рассматривается как совокупность одномерных массивов (его строк), а строка – совокупность элементов одномерного массива.
Объявление двухмерного массива с явным указанием количества элементов массива:
<тип_элементов_массива> <имя_массива>[<кол–во_строк>][<кол–во_столбцов>];
Для обращения к элементам двухмерного массива используется два индекса (индексных выражений):
<имя_массива>[<выражение1>][<выражение2>];
Индексные выражения вычисляются слева направо, полученные значения применяется после вычисления последнего индексного выражения. Элементы массивов располагаются в ОП таким образом, что быстрее изменяются самые правые индексы, т.е. элементы одномерного массива располагаются подряд, а двухмерного – по строкам.
Пример объявления двухмерного массива значений типа:
int a[m][n];
Этот массив состоит из m одномерных массивов (строк), каждый из которых содержит n элементов (столбцов). При работе с этим двухмерным массивом можно использовать одно или два индекса (индексных выражения), например, а[i][j] содержит 2 индекса. Такая запись используется для обращения к элементу, расположенному на пересечении i-й строки и j-го столбца массива. Для получения значения этого элемента вначале вычисляются индексные выражения, затем определяется адрес элемента массива в ОП и извлекается его значение.
a[i] содержит один индекс: подобная запись определяет адрес одномерного массива, т.е адрес начала i-й строки массива.
Имя массива а не содержит индекса и определяет адрес массива, т.е. адрес его нулевого элемента.
Таким образом, обращение к двухмерным массивам с помощью имени и только одного индекса определяет указатель на начало соответствующей строки массива (адрес ее нулевого элемента). Напомним, что в одномерном массиве адрес i-го элемента массива &a[i] формируется в виде а + i*sizeof(int). Используя это, определим соотношения:
a[0] &а[0][0] a + 0*n*sizeof(int);
a[1] &а[1][0] а + 1*n*sizeof(int);
a[i] &а[i][0] а + i*n*sizeof(int);
Обращение к элементам многомерного массива более детально рассмотрим на примере двухмерного массива:
int a[3][4]; //а – указатель-константа
int *р=&а[0][0]; // р – указатель-переменная
После этого указатель р можно использовать вместо указателя а для обращения к строкам или элементам массива. В ОП элементы массива а располагаются таким образом, что быстрее всех изменяется самый правый индекс, т.е. в последовательности: a[0][0] а[0][1] а[0][2] а[0][3] а[1][0] ... а[2][0] а[2][1] а[2][2] а[2][3]
При этом для обращения к массиву а можно использовать имена:
&а а &а[0][0] *а – адрес элемента 0-й строки и 0-го столбца массива а;
*(&а[0][0]) а[0][0] – значение элемента 0-й строки 0-го столбца массива а;
a[i] (а+i) *(а+i) &a[i][0] – адрес начала i-й строки, т.е. адрес элемента i-й строки и 0-го столбца;
*a[i] *(&a[i][0]) a[i][0] – значение 0-го элемента i-й строки;
a[i][j] *(*(a+i)+j) *(a[i]+j) a[i][j] – значение элемента i-й строки j-го столбца массива а;
где (а+i) *(a+i) a[i] – адрес 0-го элемента i-й строки, т.е. &a[i][0];
(*(a+i)+j) – адрес j-го элемента i-й строки, т.е. &a[i][j];
*(*(a+i)+j) – значение j-го элемента i-й строки, т.е. a[i][j].
Значение адреса начала i-й строки (адреса 0-го элемента i-й строки) на машинном уровне формируется в виде:
a[i] а+i (a+i*n*sizeof(int))
где n — количество элементов в одной строке. Таким образом, адрес (i+1)-й строки смещен относительно i-й строки на (n*sizeof(int)) байт, т.е. на одну строку массива. Выражение a[i][j] компилятор С++ переводит в эквивалентное выражение *(*(а+i)+j).
К элементам двухмерного массива можно обратиться и с помощью скалярного указателя на массив.
Например, после объявления:
int a[m][n], *р = &а[0][0]; *(р+i*n+j) // значение j-го элемента в i-й строке;
где n – количество элементов в строке; i*n+j – смещение элемента a[i][j] относительно начала массива а.
Пример 1. Дан одномерный динамический массив. Вычислить среднее арифметическое модулей элементов массива.
Ход выполнения работы
-
Алгоритмы решения задач с использованием динамических массивов схожи с алгоритмами, использующими статические массивы.
-
Написать программу, соответствующую алгоритму:
Алгоритм |
Программа |
объявление вещ: *а, sum ; цел: i, n // ввод количества элементов массива ввод n выделить динамическую память под указатель a // ввод элементов массива для i=0 до n-1 шаг 1 ввод ai все для i //сначала сумма элементов равна нулю sum=0 для i=0 до n-1 шаг 1 // в цикле изменяется номер i // элемента массива // нужный элемент добавляется к // сумме sum=sum+ai все_для i // находим среднее арифметическое sum=sum/n // печатаем полученное значение печать sum // вывод массива на экран для i=0 до n-1 шаг 1 вывод ai все_для i освободить выделенную под указатель a динамическую память
|
#include "stdio.h" #include "stdlib.h" int main ( ) { float *а, sum; int i, n; // ввод n printf ("n=" ); scanf ("%i", &n); a=(float*)malloc(n*sizeof(float)); //ввод одномерного динамического //массива с клавиатуры for ( i=0; i<=n-1; i++ ) { printf(“a%i=”,i); scanf(“%f”,a+i); } // сначала сумма элементов равна нулю sum=0; // вычисление суммы элементов for ( i=0; i<=n-1; i++ ) sum=sum+*(a+i); // находим среднее арифметическое sum=sum/n; // печатаем полученное значение printf("sred_arif=%f\n", sum); // вывод одномерного динамического // массива на экран for (i=0; i<=n-1; i++) printf ("%.3f ", *(а+i)); printf("\n"); free(a); return 1; } |
Примечание. Для выделения динамической памяти под массив из n элементов использовалась библиотечная функция malloc():
Для ввода элементов массива как обычно использовалась функция scanf(). Вторым аргументов этой функции является адрес переменной, которая получает вводимое значение. В данном примере это адрес i-го элемента динамического массива a+i. При вычислении суммы значение i-го элемента получали с помощью записи
Вывод элементов массива осуществляется при помощи функции printf(), где для вывода элементов применялась та же форма записи.
-
Создать проект и реализовать данную задачу в среде Visual C++ 6.0.
Пример 2. Сформировать двухмерный динамический массив по закону .
Ход выполнения работы
-
Алгоритмы решения задач с использованием динамических массивов схожи с алгоритмами, использующими статические массивы.
-
Написать программу, соответствующую алгоритму:
Алгоритм
Программа
объявление вещ: *а ; цел: i, n
// ввод количества строк массива
ввод n
// ввод количества столбцов массива
ввод m
выделить динамическую память под указатель a
// формирование массива построчно
для i=0 до n-1 шаг 1
для j=0 до m-1 шаг 1
aij=i+j
все для j
все для i
// вывод массива построчно
для i=0 до n-1 шаг 1
для j=0 до m-1 шаг 1
вывод aij
все для j
все_для i
освободить выделенную под указатель a динамическую память
#include "stdio.h"
#include "stdlib.h"
int main ( )
{
int *a;
int i, j, m, n;
//ввод n
printf ("n=" );
scanf ("%i", &n);
//ввод m
printf ("m=" );
scanf ("%i", &m);
//выделение динамической памяти под
//целочисленный массив из n строк и
//m столбцов
a=(int*)malloc(n*m*sizeof(int));
//формирование динамического массива
//построчно
for ( i=0; i<=n-1; i++ )
for ( j=0; j<=m-1; j++ )
{
*(a+i*m+j)=i+j;
}
//вывод динамического массива //построчно
for (i=0; i<=n-1; i++)
{
for ( j=0; j<=m-1; j++ )
printf ("%i ", *(a+i*m+j));
printf("\n");
}
//освобождение выделенной
// динамической памяти
free(a);
return 1;
}
-
Создать проект и реализовать данную задачу в среде Visual C++ 6.0.
Пример 3. Дан двухмерный динамический массив размера . Сформировать одномерный динамический массив, каждый элемент которого – произведение нечетных элементов соответствующего столбца двухмерного массива. Указать номер столбца с наименьшим произведением элементов.
Ход выполнения работы
-
Решение этой задачи было подробно рассмотрено в разделе «Двухмерные массивы».
-
Написать программу, соответствующую алгоритму:
Алгоритм
Программа
объявление вещ: *а,p,*b, цел: i, j, pmin, n, m
// ввод количества строк массива
ввод n
// ввод количества столбцов массива
ввод m
выделить динамическую память под указатель a
выделить динамическую память под указатель b
// ввод массива построчно
для i=0 до 6-1 шаг 1
// в цикле изменяется номер i строки
// массива
для j=0 до 4-1 шаг 1
// в цикле изменяется номер
// столбца массива j
// затем элемент вводится
ввод аij
все_для j
все_для i
// вычисление произведений
для j=0 до 4-1 шаг 1
// в цикле изменяется номер j столбца
// массива
//находим произведение j-го столбца
p=1
для i=0 до 6-1 шаг 1
// в цикле изменяется номер строки
// массива i
// находим нечетный элемент
если остаток от дел aij на 2 =1
//изменяем произведение
p=p*aij
все_если
все_для j
b[j]=p
все_для i
//находим минимальный элемент
//массива b
p=b0
//номер минимального элемента
pmin=0
для i=1 до 4-1 шаг 1
если p<bi
p=bi
pmin=i
все_если
все_для i
// вывод массива a построчно
для i=0 до 6-1 шаг 1
// в цикле изменяется номер i строки
// массива
для j=0 до 4-1 шаг 1
// в цикле изменяется номер j
// столбца массива
// затем этот элемент выводится на
// экран
вывод аij
все_для j
все_для i
// вывод массива b
для i=0 до 4-1 шаг 1
вывод bi
все_для i
печать pmin
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
int main()
{
float *a, p, *b;
int i, j, pmin, n, m;
//ввод n
printf ("n=" );
scanf ("%i", &n);
//ввод m
printf ("m=" );
scanf ("%i", &m);
//выделение динамической памяти под
//целочисленный массив из n строк и
//m столбцов
a=( float *)malloc(n*m*sizeof(float));
b=( float *)malloc(m*sizeof(float));
// ввод динамического массива a
// построчно
for(i=0; i<=n-1; i++)
{
for (j=0; j<=m-1; j++)
{
printf ("a[%i][%i]=",i,j);
scanf ("%f", a+i*m+j);
}
}
// вычисление произведений
for(j=0; j<=m-1; j++)
{
p=1;
for (i=0; i<=n-1; i++)
{
if(fmod(*(a+i*m+j),2)==1)
p=p*(*(a+i*m+j));
}
*(b+j)=p;
}
//находим минимальный элемент массива //b
p=*b; //нулевой элемент массива b
pmin=0;
for (i=0; i<=m-1; i++)
{
if(p>*(b+i))
{
p=*(b+i);
pmin=i;
}
}
// вывод массива a построчно
for (i=0; i<=n-1; i++)
{
for (j=0; j<=m-1; j++)
printf ("%.2f ", *(a+i*m+j));
printf ("\n");
}
printf ("\n");
// вывод массива b
for (i=0; i<=m-1; i++)
{
printf ("%.2f ", *(b+i));
}
printf ("\n");
printf ("№min=%i\n", pmin);
free(a);
free(b);
return 1;
}
-
Создать проект и реализовать данную задачу в среде Visual C++ 6.0.