Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
отчёт лр 5.docx
Скачиваний:
5
Добавлен:
01.12.2018
Размер:
82.78 Кб
Скачать

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