ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 26.06.2020
Просмотров: 131
Скачиваний: 3
Задание 1
Занести из файла в массив данные о температуре воды на Черноморском побережье за сентябрь. Определить: а) сколько за это время было дней, пригодных для купания; б) в какой из декад сентября было больше дней пригодных для купания? Программную реализацию пункта б) оформить в виде функции, в которую необходимо передать в качестве параметра массив, содержащий данные о температуре воды на Черноморском побережье за сентябрь.
Алгоритм
Начало
Ввод данных
Файл
существует
true
i<30
Вывод сообщения об ошибке
true
f >> A[i] – записываем в массив температуру
i дня
Конец
Выводим ее на экран
i++
f.close() – закрываем файл
Ввод температуры пригодной для купания
i<30
i++
false
A[i]>=t
true
K=k+1 –
увеличиваем кол-во дней
Вывод k (количество дней,
пригодное для купания)
f1(A,t) – вызов функции
f1
начало
i<10
false
i<20
false
true
b[i]>=t
true
j=j+1
true
b[i]>=t
true
h=h+1
i<30
false
true
b[i]>=t
true
k=k+1
Вывод h, j, k.
Конец
Текст программы
#include <iostream>
#include <stdio.h>
#include <fstream>
using namespace std;
void f1(float *b,float t)
{
int i,h,j,k;
h=j=k=0;
for (i=0;i<10;i++)
{
if (b[i]>=t)
h=h+1;
}
for (i=10;i<20;i++)
{
if (b[i]>=t)
j=j+1;
}
for (i=20;i<30;i++)
{
if (b[i]>=t)
k=k+1;
}
cout<<"\n pervaja dekada: "<<h<<" dney \n vtoraja: "<<j<<" dney \n tret'ja:"<<k<<" dney \n";
if (h>j && h>k) cout<<"v pervuju dekadu bilo bol'cshe vsego dney, prigodnih dlja kupanija: "<<h;
if (j>h && j>k) cout<<"vo vtoruju dekadu bilo bol'cshe vsego dney, prigodnih dlja kupanija: "<<j;
if (k>j && k>h) cout<<"v tret'u dekadu bilo bol'cshe vsego dney, prigodnih dlja kupanija: "<<k;
if (h==j || h==k || j==h || j==k) cout<<"\ndekadi, v kotoroi bol'she vsego dney, prigodnih dlja kupanija, ne suchestvuet";
cout<<endl;
}
int main()
{
float A[30];
float t;
int k,i;
ifstream f;
f.open("D:\\1.txt");
k=0; //schetchik dney
if (f)
{ cout << "Read file ! \n";
for (i=0;i<30;i++)
{ f >> A[i];
cout<<" "<<i+1<<" den' - "<<A[i]<<" C \n ";
}
cout << "\n";
f.close();}
else cout << "File not found \n";
cout<<"\n vvedite temperaturu, prigodnuu dlja kupanija(gradusi Celsija): ";
cin>>t;
cout<<"\n";
for (i=0;i<30;i++)
{
if (A[i]>=t)
{
cout<<i+1<<" den' prigoden dlja kupanija\n";
k=k+1;}
}
if (k==0) cout<<"\n kol-vo dney prigodnih dlja kupania ravno 0";else
cout<<"\n kol-vo dney prigodnih dlja kupania ravno "<<k;
cout<<"\n";
f1(A,t);
system("pause");
}
Тесты:
Задание 2
Магическим квадратом порядка n называется квадратная таблица размером n x n, состоящая из чисел 1, 2, ….., n2, так, что суммы по каждому столбцу, каждой строке и каждой из двух диагоналей равны между собой. В файле хранится целочисленная квадратная матрица. Записать целочисленную квадратную матрицу в двумерный массив. Проверить, является ли заданная целочисленная квадратная матрица магическим квадратом.
Алгоритм
Начало
файл существует
вывод “error”
true
f>>n;f>>m – считываем из файла в
переменные n и m
кол-во строк и столбцов
конец
true
i<n
false
true
i++
j<n
j++
false
true
f>>a[i][j] считываеем элементы из файла
в массив
i<n
j<n
i++
true
false
true
false
вывод элементов
массива на экран
magic(a,n,m)
Magic==1
true
false
Вывод
сообщения:”Магический
квадрат”
Вывод сообщения:”Не
магический квадрат”
Конец
Конец
Функция magic – функция, возвращающая значение 1, если матрица является магическим квадратом, и 0, если матрица им не является.
Алгоритм работы функции:
Первым делом функция считает сумму элементов первой строки матрицы, затем осуществляется подсчет суммы элементов оставшихся строк и сравнение их суммы с суммой элементов первой строки, если в какой-либо момент суммы не совпадают, то функция возвращает значение 0.
Далее функция считает сумму элементов первого столбца, сравнивает ее с суммой элементов первой строки, если суммы не совпадают, то функция возвращает значение 0, следующим шагом является сравнение суммы элементов первого столбца с остальными суммами элементов столбцов, если суммы не совпадают, то функция возвращает значение 0.
После функция считает сумму элементов главной диагонали, сравнивает ее с суммой элементов столбца. И сумму побочной диагонали. Если все суммы равны, то функция возвращает значение 1, в противном случае функция возвращает значение 0.
Текст программы
#include <iostream>
#include <fstream>
using namespace std;
int magic(int **a,int n,int m)
{
int k,ssto,sd1,sd2,l,sstr,i,j;
sd1=0;sd2=0;k=0;l=0;
for (i=0;i<1;i++)
{
for (j=0;j<m;j++)
l=l+a[i][j];//summa 1 stroki
}
//_______________________
for (i=1;i<=n;i++)
{
sstr=0;
if (i==n) break;
for (j=0;j<m;j++)
{
sstr=sstr+a[i][j];//summa stroki
k=sstr;
}
if (l!=k) return 0;
}
//______________________________________
l=0;
for (j=0;j<1;j++)
for (i=0;i<n;i++)
l=l+a[i][j]; // summa 1 stolbza
//_______________________________
for (j=1;j<=m;j++)
{
ssto=0;
if (j==m) break;
for (i=0;i<n;i++)
{
ssto=ssto+a[i][j];// summa stolbzov
k=ssto;
}
if (l!=k) return 0;
}
//____________________________
for (i=0;i<n;i++)
for (j=0;j<m;j++)
if (i==j) sd1=sd1+a[i][j];//glavnaja diagonal'
if (sd1!=k) return 0;
//_______________________________
for (i=0;i<n;i++)
for (j=0;j<m;j++)
if(i+j+1==n)sd2=sd2+a[i][j];//pobochnaja diagonal'
if (sd2!=k) return 0;else return 1;
}
int main()
{
int **a,i,j,n,m,mag;
ifstream f;
f.open("D:\\1.txt");
if(f)
{
cout<<"\n read fail \n";
f>>n;f>>m;
a = new int *[n];
for (i=0;i<n;i++)
a[i]=new int [m];
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
f>>a[i][j];
}
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
//____________________________________________
mag=magic(a,n,m);
if (mag==1) cout<<"\n kvadrar magicheskii \n";else cout<<"\n kvadrar ne magicheskii \n";
}
else cout<<"\n error open fail (neophodimo sozdat' fail)\n";
system("pause");
}
Тесты:
Вопросы (одномерные массивы)
5. Как передаются одномерные массивы в качестве параметров в функцию?
Одномерные массивы передаются в функцию по адресу.
Если в роли параметра функции выступает массив, то в функцию передается адрес его первого элемента (адрес a[0]). В результате, вызываемые функции могут изменять значения элементов в исходных массивах и возвращать их в главную функцию.
Для передачи адреса первого элемента одномерного массива необходимо в списке формальных параметров объявить переменную указатель или имя массива с пустыми квадратными скобками.
пример: void F(int a[ ]) или voif F(int *a)
В списке фактических параметров всегда указывается имя массива без квадратных скобок. Имя статического массива, как уже сказано, является константным указателем на первый элемент массива. Имя динамического массива – переменная указатель.
пример: F(a)
Информация о количестве элементов массива должна передаваться через отдельный параметр.
4. Как связаны массивы и указатели в С и C++? Операции над указателями, примеры.
Указатель – это переменная, значением которой является адрес памяти, по которому храниться объект определенного типа (другая переменная).
C помощью указателей можно передавать адреса фактических параметров функциям и адреса функций в качестве параметров, создавать новые переменные в процессе выполнения программы, обрабатывать массивы, строки и структуры.
Сложение и вычитание указателей с константой n означает, что указатель перемещается по ячейкам памяти на столько байт, сколько занимает n переменных того типа, на который он указывает, т. е. n * sizeof( тип).
Разность двух указателей - это разность их значений, деленная на размер типа в байтах, т. е. вычитание двух указателей определяет, сколько переменных данного типа размещается между указанными ячейками. Так, разность указателей на третий и нулевой элементы массива равна трем, а на третий и девятый - шести. Суммирование двух указателей не допускается.
Инкремент перемещает указатель к следующему элементу массива, а декремент - к предыдущему.
К указателям так же применимы операции отношения ==, !=,<,>, <=, >=. Иными словами, указатели можно сравнивать. Например, если i указывает на пятый элемент массива, a j - на первый, то отношение i>j истинно. Кроме того, любой указатель всегда можно сравнить на равенство с нулем.
Однако, все эти утверждения верны, если речь идет об указателях, ссылающихся на один массив. В противном случае результат арифметических операций и операций отношения будет не определен.
Значение одного указателя можно присвоить другому. Если указатели одного типа, то для этого применяют обычную операцию присваивания.
Эти операции применимы только к указателям одного типа и имеют смысл в основном при работе со структурными типами данных, например с массивами.
3. Понятие динамического массива. Как в С и С++ создаются одномерные динамические массивы?
Динамический массив – это массив, память под который выделяется в процессе выполнения программы. Выделение памяти может выполняться функциями calloc, malloc или операцией new.
Например, оператор int *mas=new int[10]; означает, что описан указатель mas и ему присвоен адрес начала непрерывной области динамической памяти, выделенной с помощью операции new: Выделено столько памяти, сколько необходимо для хранения 10 величин типа int.
Имя массива является указателем на его нулевой элемент (т. е. хранит адрес элемента массива с индексом ноль):
для массива со статическим выделением памяти – это константный указатель;
для динамического массива – это указатель - переменная.
Обращение к i-му элементу динамического массива можно выполнить, как обычно mas [i] (т. е. с использованием имени массива и индекса элемента), или другим способом: * (mas +i) (с использованием арифметической операции сложения указателя с числом для определения адреса элемента массива и операции разыменования для обращения к значению элемента массива) . Важно следить за тем, чтобы не выйти за границы выделенного участка памяти.
Когда динамический массив (в любой момент работы программы) перестает быть нужным, то память можно освободить с помощью функции free или оператора delete.
2. Понятие динамической переменной. Как создаются динамические переменные в С и С++?
Существует способ выделения памяти для переменных во время выполнения программы. Такие переменные называются динамическими, они создаются по требованию программы и запоминаются в блоках памяти переменного размера, принадлежащих к специальным образом организованной области памяти – куче.
Существует несколько способов выделения памяти в куче для динамических переменных.
Функция malloc резервирует непрерывный блок ячеек памяти для хранения указанного объекта и возвращает указатель на первую ячейку этого блока. Параметр size - целое беззнаковое значение, определяющее размер выделяемого участка памяти в байтах. Если резервирование памяти прошло успешно, то функция возвращает переменную типа void *, которую можно привести к любому необходимому типу указателя.
Функция calloc выделяет num элементов по size байт. Эта функция возвращает указатель на выделенный участок или NULL при невозможности выделить память. Особенностью функции является обнуление всех выделенных элементов.
Функция realloc изменяет размер выделенной ранее памяти. Параметр р - указатель на область памяти, размер которой нужно изменить на size. Если в результате работы функции меняется адрес области памяти, то новый адрес вернется в качестве результата. Если фактическое значение первого параметра NULL, то функция realloc работает так же, как и функции malloc, то есть выделяет участок памяти размером size байт.
Для освобождения выделенной памяти в С используется функция free. Параметр р - указатель на участок память, ранее выделенный функциями malloc, calloc или realloc.
Операции new и delete аналогичны функциям malloc и free. Операция new выделяет память. Ее единственный аргумент - это выражение, определяющее количество байтов, которые будут зарезервированы. Возвращает операция указатель на начало выделенного блока памяти. Операция delete освобождает память, ее аргумент - адрес первой ячейки блока, который необходимо освободить.
Вопросы (двумерные массивы)
2.Как создаются двумерные динамические массивы в С++ ? Примеры.
Основной способ работы с динамическими матрицами базируется на использовании двойных указателей.
В операторе 1 объявляется переменная типа «указатель на указатель на int» и выделяется память под массив указателей на строки массива (количество строк – n).
В операторе 2 организуется цикл для выделения памяти под каждую строку двумерного массива у.
В операторе 3 каждому элементу массива указателей на строки двумерного массива присваивается адрес начала участка памяти, выделенного под строку двумерного массива. Каждая строка состоит из m элементов типа int.
int **a = new int *[n]; // 1
for (int i=0; i<n; i++) // 2
a[i] = new int [m]; // 3
3.Как передаются двумерные массивы в качестве параметров в функцию? Примеры.
Двумерные массивы, как и одномерные, передаются в функцию по адресу (передается адрес первого элемента первой строки - &a[0][0]). Поэтому функция работает с самим массивом, а не с его копией, и может его изменить.
Если в функцию передается двумерный статический массив, то необходимо не только передать адрес первого элемента первой строки - &a[0][0], но дать возможность компилятору определять адреса начала всех строк передаваемой матрицы. Для этого в списке формальных параметров у двумерного массива обязательно нужно указывать вторую размерность, которая задает количество элементов в строке (количество столбцов) матрицы.
Если в функцию передается двумерный динамический массив, то в списке формальных параметров для параметра массива достаточно объявить двойной указатель (т. е. указатель на массив указателей на строки матрицы).
В операторе вызова функции в списке фактических параметров и в том и в другом случае для параметра массива указывается имя массива.
Информация о количестве элементов двумерного массива (количество строк и количество столбцов матрицы) должна передаваться через отдельные параметры.
Пример:
Передача двумерного статического массива в качестве параметра в функцию:
const int row = 5;
const int row = 5;
void Func (int arr [row][col], int rows, int cols);
или
void Func (int arr [][col], int rows, int cols)
Передача двумерного динамического массива в качестве параметра в функцию:
void Func (int **arr, int rows, int cols);
Вызов функции:
Func (arr1, r, с);
4-5.Как организуется запись двумерного массива в текстовый (бинарный) файл и чтение двумерного массива из текстового (бинарного) файла?Примеры.
Запись и чтение элементов двумерного массива в файл организуется с помощью цикла, в котором считывается (записывается) элемент в файл.
Например:
// запись элементов из тестового файла в массив
for(i = 0;i < nrow;i++)
{ for(j = 0;j < ncol;j++)
f2 << a[i][j]<< " ";
f2 << "\n";
//чтение элементов массива из тестового файла
for(i = 0; i < nrow; i++)
for(j = 0;j < ncol; j++)
f >> a[i][j];
cout << "\n";
// запись элементов массива в бинарный файл
for(i = 0; i < nrow; i++)
for(j = 0; j < ncol; j++)
fwrite(&a[i][j],sizeof(int),1, f);
//чтение элементов массива из бинарного файла
for(i=0; i<n; i++)
for (j=0; j<m; j++)
fread(&b[i][j],sizeof(int),1, f);