Реализация алгоритмов задач второго типа

Задача 1.В матрице X ={хij}3х6 вещественных чисел первый элемент каждой строки поменять местами с минимальным элементом этой строки. Вывести матрицу X после обмена. ( Для заполнения матрицы воспользуемся датчиком случайных чисел).

Да
X[i][jmin]=X[i][0] X[i][0]=min
Х[i][j]<min  
min=X[i][j] jmin=j    
i = 0, 3
J = 0, 6
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
i = 0, 3
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
Да
Х[i][j]<min  
J = 0, 6
i = 0, 3
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
Да
Х[i][j]<min  
J = 0, 6
i = 0, 3
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
min=X[i][j] jmin=j    
Да
Х[i][j]<min  
J = 0, 6
i = 0, 3
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
min=X[i][j] jmin=j    
Да
Х[i][j]<min  
J = 0, 6
i = 0, 3
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
min=X[i][j] jmin=j    
Да
Х[i][j]<min  
J = 0, 6
i = 0, 3
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
X[i][jmin]=X[i][0] X[i][0]=min
min=X[i][j] jmin=j    
Да
Х[i][j]<min  
J = 0, 6
i = 0, 3
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х
Вывод матрицы Х
Конец
X[i][jmin]=X[i][0] X[i][0]=min
min=X[i][j] jmin=j    
Да
Х[i][j]<min  
J = 0, 6
i = 0, 3
min=106
НАЧАЛО
Вывод Матрицы Х
Инициализация матрицы Х

Текст программы:

#include "stdafx.h"

#include<math.h>

void main()

{

float X[3][6]; // описание матрицы X

int i,j,jmin;

float min;

for(i=0; i<3; i++) /* заполнение матрицы случайными числами*/

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

X[i][j]=rand()/100;

printf(" матрица X\n");

for(i=0; i<3; i++) //вывод матрицы до перестановки

{

for (j=0; j<6; j++) printf("%8.2f",X[i][j]);

printf("\n");

}

for(i=0; i<3; i++) //цикл по строкам

{

min=+1E6; // установка начального значения min

for (j=0; j<6; j++) //цикл по столбцам

if (X[i][j]<min) // поиск минимума

{

min=X[i][j];

jmin=j;

}

X[i][jmin]=X[i][0]; // перестановка первого элемента

X[i][0]=min; // матрицы с наименьшим

}

for(i=0; i<3; i++) //вывод матрицы после перестановки

{

for (j=0; j<6; j++) printf("%8.2f",X[i][j]);

printf("\n");

}

}

Задача 2.Дана матрица вещественных чисел С = {сij}8х4. Вычислить среднее арифметическое каждого столбца. Результат оформить в виде одномерного массива S = {sj};j = Реализация алгоритмов задач второго типа - student2.ru .

#include "stdafx.h"

void main()

{ float C[8][4];

float S[4];

int i, j;

printf("Введите матрицу С:\n");

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

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

scanf("%f",&C[i][j]);

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

{

S[j]=0; //начальная установка элемента массива для сумм

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

S[j]= S[j] + C[i][j]; //накопление суммы j-го столбца

S[j]=S[j]/8; //вычисление среднего значения суммы j столбца

}

for (j= 0; j<4; j++) printf("%8.2f",S[j]); // вывод всех сумм

printf("\n");

}

В приведенной выше программе для вычисления каждого элемента S[j] организован двойной цикл, в котором индекс j является внешним параметром цикла, а индекс i - внутренним.

Приведем вариант программы без использования одномерного массива S.

#include "stdafx.h"

void main()

{ float C[8][4];

float S;

int i, j;

printf("Введите матрицу С:\n");

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

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

scanf("%f",&C[i][j]);

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

{

S=0;

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

S= S + C[i][j];

S = S/8;

printf("Среднее арифметическое %d-го столбца=%8.2f\n", j, S);

}

}

Подпрограммы

Структура сложной программы

Любая программа на языке высокого уровня может быть разбита на ряд логически завершенных программных единиц - подпрограмм. Такое разделение вызвано двумя причинами.

1. Экономия памяти. Каждая подпрограмма записывается в программе один раз, в то время как обращаться к ней можно многократно из разных точек программы.

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

В языке Си существует один вид подпрограмм, который называется функция. Каждая программа должна иметь главную функцию (main), которая служит точкой входа в программу. Кроме главной функции в программе может быть оформлено произвольное число функций.

Описание подпрограммы само по себе никаких действий не вызывает. При запуске программы выполнение начинается с операторов главной функции main(). Чтобы выполнить подпрограмму, в нужной точке главной функции необходимо записать обращение к подпрограмме.

Ниже схематично приведена структура программы, в которой описана подпрограмма-функция.

#include "stdafx.h"

//Раздел описаний функций

тип имя_функции(тип имя_параметра_1, тип имя_параметра_2,...)

{

тело функции

}

………………………………….

main() //начало главной функции

{

Обращение к подпрограмме:

……………………..

} //конец главной функции

Функции

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

Каждая функция по отношению к другим является внешней.

Общий вид описания функции

Описание функции содержит заголовок со списком формальных параметров и тело функции.

Тип Имя(список формальных параметров)

{

Описание локальных переменных;

Операторы тела функции;

return результат;

}

Тип указываемый в заголовке функции определяет тип результата ее работы, который будет возвращаться в точку вызова. Если тип не указан, то по умолчанию подразумевается int (целый). Для возврата значения в теле функции должен быть оператор return. В дальнейшем будем называть такую функцию типизированной.

Если функция не должна возвращать результат, то она считается не- типизированной, что задается ключевым словом void, стоящим на месте типа. В этом случае оператор return в функции не требуется.

void Имя(список формальных параметров)

{

Описание локальных переменных;

Операторы тела функции;

}

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

Параметры, указанные в заголовке функции, называются формальными, а параметры, указываемые при ее вызове – фактическими.

Рассмотрим пример оформления функции для вычисления максимального значения из двух заданных.

#include "stdafx.h"

int max(int a, int b)

{

int c;

if (a>b)

c=a;

Else

c=b;

return c;

}

void main()

{ int x,y,z;

printf("Введите x и y:");

scanf("%d%d",&x,&y);

z=max(x,y);

printf("max=%d\n",z);

}

Обращение к функции

Обращение к типизированной функции не является специальным оператором, а включается в состав выражения. Результат выполнения функции возвращается в основную программу через имя функции. Обращение к функции записывается аналогично записи стандартной функции (например, sin(x), ехp(x) и т.п.) в виде операнда:

<имя функции>(<список фактических параметров>);

При вычислении выражения операнд обращения к функции заменяется значением функции.

Пример программы с функцией

Вычислить значение: Z = Реализация алгоритмов задач второго типа - student2.ru ,

где а - заданное вещественное число.

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

Реализация алгоритмов задач второго типа - student2.ru

где i – номер шага вычисления (умножения);

n – число шагов.

При описании функции надо с помощью списков параметров (формальных и фактических) связать формальный параметр x с основанием степени, параметр п — с показателем. Поскольку в задаче требуется вычислить три раза операцию возведения в степень, то в главной функции main() будет организован вызов этой функции из выражения.

#include "stdafx.h"

float ST(float x, int n) //начало функции ST

{

int i;

float P;

P=1;

for( i=1; i<= n; i++)

P = P*x;

return P;

} // конец функции ST

void main()

{

float a,Z;

printf("Введите число а:");

scanf("%f",&a);

Z = (ST(a, 5) + ST(1/a, 5))/(2* ST(a, 7));

printf("Z=%f\n", Z);

}

В процессе выполнения программы после ввода заданного числа а вычисляется значение Z по формуле.В данной формуле обращение к функции ST осуществляется с помощью трех операндов.

При каждом вызове функции происходит соответствующая замена формальных параметров (х, n) на фактические. Вычисленный результат возвращается в выражение. Далее вычисляется значение Z и выводится на экран.

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

Прототип функции по форме аналогичен заголовку функции, в конце которого ставится ";".

Например, рассмотрим предыдущую программу:

#include "stdafx.h"

// прототип функции ST

float ST(float , int );

// функция main

void main()

{ float a,Z;

printf("Введите число а:");

scanf("%f",&a);

Z = (ST(a, 5) + ST(1/a, 5))/(2* ST(a, 7));

printf("Z=%f\n", Z);

}

// функция ST

Float ST(float x, int n)

{

int i;

float P;

P=1;

for( i=1; i<= n; i++)

P = P*x;

return P;

}

Согласование параметров

Формальные и фактические параметры должны быть согласованы друг с другом по количеству, типу и порядку следования. Это означает, что количество формальных параметров должно быть равно количеству фактических параметров, и каждый формальный параметр должен иметь тот же тип и занимать в списке то же место, что и соответствующий ему фактический параметр.

Механизм замены параметров

В языке С++ существует два механизма передачи параметров в функции: по значению и по адресу.

Как правило, параметры функции (кроме массивов и указателей) передаются по значению. Параметры, передаваемые по значению, играют роль входных параметров. Фактическим параметром, передаваемым по значению, может быть константа, переменная или выражение. Для них при вызове функции в памяти компьютера временно выделяются ячейки, в которые передаются копии значений фактических параметров. При выполнении функции значения в этих ячейках могут измениться, однако соответствующие им фактические параметры останутся без изменения.

Результат работы функции возвращается в точку вызова с помощью оператора return. Таким образом, функция может вернуть только одно скалярное значение. Если функция должна вернуть несколько результатов, то этот возврат реализуется с помощью указателей, т.е. параметров, передаваемых по адресу.

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

Рассмотрим два примера, иллюстрирующих механизмы передачи параметров

Пример 1 Пример 2

#include "stdafx.h" #include "stdafx.h"

void Z (int у) void Z (int *у)

{ {

y=l; *y=1;

} }

void main() void main()

{ int х; { int х;

x=0; х=0;

Z(x); Z(&x);

printf("x=%d", x); printf("x=%d", x);

} }

В примере 1 процедура Z содержит формальный параметр у, который передается по значению, поэтому его измене­ние в процедуре (у=1;) не влияет на значение фактического параметра х. После выполнения программы на экран будет выведено: х=0.

В примере 2 формальный параметр у – это указатель. Это означает, что в функции изменяется значение в той ячейки памяти, адрес которой передавался в функцию Z, т.е. по адресу фактического параметра X. На экран будет выведено: х = 1.

Наши рекомендации