Файл: Практикум по дисциплине Программирование для образовательной программы по направлению 09. 03. 01 Информатика и вычислительная техника.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 10.01.2024
Просмотров: 14
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Сибирский государственный университет
телекоммуникаций и информатики
Лаботораторный практикум
по дисциплине «Программирование»
для образовательной программы по направлению 09.03.01
«Информатика и вычислительная техника»,
Профиль «Программное обеспечение средств вычислительной техники и
автоматизированных систем».
квалификация (степень) бакалавр
форма обучения заочная
Факультет информатики и вычислительной техники (ИВТ)
Кафедра прикладной математики и кибернетики (ПМиК)
Разработчик: доцент кафедры ПМиК, к.т.н., доцент Перцев Игорь Владимирович
Новосибирск 2017
1 часть
Лабораторная работа №1
Программы линейной и разветвленной структуры
1. ЦЕЛЬ РАБОТЫ: приобретение практических навыков работы в интегрированной среде C, изучение структуры программы на языке С.
2. ОСНОВНЫЕ СВЕДЕНИЯ
Чаще всего линейные алгоритмы используются для программирования вычислений по формулам. В этом случае удобно использовать набор стандартных функций Си, содержащихся в заголовочном файле math.h :
Sin (x) - sin x; cos (x) – cos x ; tan(x) - tg х ; log (x) - ln x; log10(x) – lg x; exp(x) - показательная функция ex ; sqrt (x)- корень квадратный от х; роw(x, y) – x в степени y; abs(x)- модуль x.; acos(x) – arccos x; asin(x) – arcsin x; atan(x)- arctg x; sinh(x)- sh x; cosh (x) – ch x; tanh(x)-th x.
Для тригонометрических функций аргумент х измеряется в радианах и имеет тип double, как и значения функций.
Пример программы линейной структуры
Вычислить площадь и стороны прямоугольного треугольника, если известны гипотенуза c и угол x. Для вычислений воспользуемся формулами :
a=csin x; b=ccos x; S=ab ;
Программа вычислений имеет вид:
//lab1_prim.c вычисление высот и площади треугольника
#include
#include
main() //главная функция
{ float a,b,c,x, S; //описание переменных вещественного типа
printf (“\n Введите гипотенузу и угол треугольника ”);
scanf (“%f%f “,&c,&x); // ввод значений вещественного типа
a=c*sin(x);
b=c*cos(x);
S=a*b;
printf (“\n Результаты: a=%7.2f b=%7.2f S=%7.2f “,a, b, S);
return 0;
}
Комментарий в программе не влияет на компиляцию программы, а служит для разъяснения действий основных блоков текста и программы в целом. Однострочный комментарий действует от двух символов // до конца строки. Многострочный комментарий заключается в пары символов /* и */.
Вторая строка программы #include
Программа на языке Си состоит из ряда функций, из которых функция main (главная) является обязательной и служит точкой входа в программу. В круглые скобки заключаются параметры функции, причем наличие круглых скобок обязательно, если даже список параметров пуст. В фигурные скобки заключаются составной оператор (несколько операторов). Для придания тексту программы наглядности открывающая и соответствующая ей закрывающая фигурные скобки печатаются на одном уровне, а заключенный между ними текст, сдвигается на 1-2 символа вправо, вложенный блок также сдвигается вправо и т.д. Образуется иерархия вложенных блоков, придающая программе на Си характерный вид.
В программе описаны переменные a, b, c, х, S вещественного типа (float). В отличие от других языков в Си учитывается регистр при определении имени переменной, т.е. s и S – разные переменные. Функции printf и scanf содержатся в заголовочном файле stdio.h и служат для вывода на экран и ввода с клавиатуры соответственно. Управляющие символы \n в функции printf служат для перевода на новую строку. Символ & в функции scanf указывает на адрес вводимой переменной. Ввод и вывод переменных вещественного типа производится в формате f. Признаком форматного вывода в функции printf является %. При выводе между знаком процента и форматной переменной f можно включить общую ширину поля вывода и число позиций после десятичной точки. Оператор return 0; служит для выхода из функции main в Интегрированную Среду, 0 является признаком успешного окончания программы. Завершает текст программы закрывающая фигурная скобка, означающая конец функции main.
Алгоритм разветвленной структуры - это алгоритм, в котором вычислительный процесс осуществляется по одной из ветвей. Если количество ветвей две – то используется условный блок, если больше – то множественный выбор. В программах используют соответственно условный оператор IF или оператор SWITCH для реализации разветвленного алгоритма.
2.1. Условный оператор IF
Условный оператор в языке Си имеет формат:
if (условие) оператор1; else оператор2; (полная форма) или
if (условие) оператор1; (сокращенная форма).
Если оператор1 и оператор2 состоят из одного оператора, то в фигурные скобки они не заключаются. Если оператор1 и/или оператор2 являются составным оператором (несколько операторов), то он заключается в фигурные скобки. Условие всегда заключается в круглые скобки.
В качестве примера приведем программу вычисления наибольшего из значений функции y1=x²+1, y2=7-x² , y3=x+1 для любого х.
//lab2_prim1.c
#include
main()
{ float x,y1,y2,y3,max;
printf("Введите x\n"); scanf(“%f “,&x);
y1=x*x+1; y2=7-x*x; y3=x+1;
if (y1>y2) max=y1; else max=y2;
if (y3>max) max=y3;
printf (“ x=%8.2f y1=%8.2f y2=%8.2f y3=%8.2f max=%8.2f\n”,x,y1,y2,y3,max); }
2.2 Множественный выбор
В программах с множественным выбором используется переключатель switch , который сравнивает значение выражения, указанного за ним, и выполняет один из операторов, метка которого совпадает с этим значением. Общий вид:
Switch (выражение)
{ case метка_1: список_операторов_1;
……………………………………….
case метка_n: список_операторов_n;
default : операторы; }
Значения выражения и меток должны быть целочисленными константами.
Например, определим количество дней по введенному номеру месяца.
//lab2_prim2.c множественный выбор
#include
#include
int m;
main()
{
printf("\n Введите номер месяца :"); scanf("%d",&m);
printf("\n В %4d месяце дней: ",m);
switch(m){
case 1: case 3: case 5: case 7: case 8: case 10: case 12:printf("тридцать один\n");break;
case 2: printf ("двадцать восемь \n");break;
case 4: case 6: case 9: case 11: printf("тридцать\n");break;
default: printf("\n Номер месяца неверен \n");}
getch ();
}
В примере программы, если номер месяца превышает 12, выводится сообщение о неверном вводе месяца, для чего используется default. Оператор break служит для прерывания цикла проверки и перехода в конец переключателя. В случае отсутствия break, происходит переход на следующую ветвь. Функция getch, подключающаяся заголовочным файлом conio.h, ожидает нажатия любой клавиши. Это позволяет просмотреть результаты, не используя ALT+F5 для просмотра экрана пользователя.
3. ВЫПОЛНЕНИЕ РАБОТЫ
Составить программы разветвляющейся структуры согласно вариантам
Варианты задания
-
Даны четыре числа. На сколько их сумма меньше их произведения? -
Даны четыре числа. Вычислить сумму положительных среди них чисел. -
Даны четыре числа. Вычислить произведение отрицательных среди них чисел. -
Даны четыре числа. Все отрицательные среди них числа заменить на 0. -
Даны четыре числа. Определить сколько среди них отрицательных и сколько положительных. -
Даны четыре числа. Определить порядковый номер наименьшего среди них. -
Даны два числа. Большее из этих двух чисел заменить их полусуммой, а меньшее удвоенным произведением. -
Даны три числа. Меньшее среди них заменить на 0 .
9) Даны четыре числа. Найти разность между наибольшим и наименьшим среди них.
10) Даны три числа K, M и N. Поменять их значения местами таким образом, чтобы K < M < N.
4. КОНТРОЛЬНЫЕ ВОПРОСЫ
-
Что такое алгоритм линейной структуры, программа линейной структуры? -
Для чего используются заголовочные файлы? -
Структура программы на языке Си. -
Сравните виды условных операторов Си. -
Всегда ли ставятся скобки и какие в условном операторе? -
Зачем ставятся в переключателе операторы break и default? -
Как будет работать программа из примера без break?
Лабораторная работа №2
Программы циклической структуры. Обработка статических массивов.
1. ЦЕЛЬ РАБОТЫ: приобретение практических навыков в составлении алгоритмов и программ циклической структуры и обработки массивов.
2. ОСНОВНЫЕ СВЕДЕНИЯ
Операторы циклов
В языке Си существует 3 вида циклов: 1) цикл с параметром или цикл типа for; 2) цикл с предусловием или цикл типа while, 3) цикл с постусловием или цикл типа do ... while . Во всех этих циклах условие продолжения цикла заключается в круглые скобки. В циклах типов for и while повторяющаяся часть состоит из одного оператора, если требуется выполнить в цикле несколько операторов, они заключаются в фигурные скобки, образуя составной оператор. В цикле с постусловием тело цикла помещается между словами do и while. В отличие от цикла с предусловием, цикл с постусловием выполнится хотя бы один раз. Циклы с пред- и постусловием продолжаются, если условие продолжения истинно.
Цикл с параметром
Для цикла типа for заголовок состоит из трех разделов: инициализации (присваивания начальных значений), проверки условия повторения, модификации (изменения параметров). Разделителем между разделами заголовка служит запятая.
Пример вычисления суммы квадратов натурального ряда чисел от 1 до n.
S= = 12 + 2 2 + . . . + n 2.
//lab3_1.c сумма квадратов натурального ряда
#include
main()
{ int S,n,i;
printf(“Введите n ”); scanf(“%d”,&n);
for (S=0, i=1; i<=n; i++)
S+=i*i; // соответствует S=S+i*i
printf (“n=%d S=%d”,n,S);
}
В разделе инициализации присваиваются начальные значения переменным S и i. При i, не превышающем n, цикл повторяется, иначе выполняется выход из цикла. Оператор инкремента i++ (или декремента i--), эквивалентен i=i +1 (i=i-1). Для досрочного выхода из цикла и перехода на следующий оператор после цикла используется оператор break. Для пропуска всех операторов, оставшихся до конца тела цикла и перехода к следующему повторению цикла используется оператор continue.
Циклы с неизвестным количеством повторений
Изменим условие в предыдущем примере: Определить число n, при котором сумма чисел S предыдущего ряда не превысит величину K, введенную с клавиатуры. Такую программу можно реализовать с помощью циклов предусловия или постусловия следующим образом:
//lab3_2 циклы while и do…while
#include
#include
main()
{int K,S, i;
clrscr(); // очистка экрана перед выводом
printf (“Введите К ”); scanf (“%d”, &K);
// цикл с предусловием //цикл с постусловием
S=0; S=0; i=0;
i= 0; do
while ( S
while ( S
printf (“n=%d S=%d\n”, i, S);
getch();
}
Отличие этих программ: если ввести К<1, то в программе с предусловием получим S=0, i=0 ; а в программе с постусловием S=1, i=1.
Массивы - структурированный тип данных с элементами одного типа, имеющий одно имя и определенное количество элементов. Количество элементов определяет размер массива. Порядковый номер элемента массива называется его индексом. Число индексов называется размерностью массива, например, массив с двумя индексами называется двумерным массивом. Строка символов является массивом символов, вектор – массив чисел, матрица – массив векторов. Обработка массивов выполняется следующим образом: описание, ввод или инициализация элементов массива, преобразование и вывод.
При описании массивов после имени в квадратных скобках указывается число его элементов. В языке Си индекс элемента массива начинается с нуля, поэтому индекс последнего элемента массива на 1 меньше числа элементов в данном массиве.
Пример обработки одномерного массива
Дан массив из 50 целых чисел. Найти наибольший элемент в массиве и его порядковый номер.
# include
#include
# define n 50 // определение константы n=50
int i, max, nom, a[n]; //описание массива целых чисел из n элементов
main()
{ for (i=0; i
{ printf( “\n Введите элемент массива ”);
scanf ("%d", &a[i]) };
for (i=1,max=a[0],nom=0; i
if (max
{nom=i; max=a[i];}
printf("\n Вывод элементов исходного массива : \n");
for (i=0; i
printf ("\n Максимальное число в массиве %4d, его индекс %4d " , max, nom+1);
getch();
}
Многомерные массивы задаются указанием каждого измерения в квадратных скобках. Например, оператор int matr [6] [8]; задает описание матрицы из 6 строк и 8 столбцов. Нумерация строк и столбцов начинается с 0. При инициализации двумерного массива он представляется как массив из массивов, при этом каждый массив заключается в свои фигурные скобки, либо задается общий список в том порядке, в котором элементы располагаются в памяти:
int mas [] [2]= { {1,2}, {0,2}, {1,0}};
int mas [3][2]={1,2,0,2,1,0};
3. ВЫПОЛНЕНИЕ РАБОТЫ
Даны вещественные числа a,b. Значения функции (согласно вариантам) записать в массив. Вычислить значение интеграла, используя:
1) Формула трапеций
I1=h*(a[0]/2+a[1]+a[2]+…+a[N-1]+a[N]/2)
2) Формула Симпсона
I2=h/3*( a[0]+a[N] + 4*(a[1]+a[3]+…+a[N-1]) +
2*(a[2]+a[4]+…+a[N-2]))
h=(b-a)/n, N=100.
Сравнить полученные по двум формулам значения интегралов.
1. f(x)=x2/(10+x3); a=-2; b=5;
2. f(x)=(2.5x2-0.1)/(tg x+sin x); a=4; b=6;
3. f(x)=(x+1)2√lg x; a=2; b=10;
4. f(x)=x2 ln x /(1+x)2; a=1; b=20;
5. f(x)=1/((0.5+0.1x3)√x); a=0.1; b=2.1;
6. f(x)=x 2√(2+3x)3; a=0.5; b=2.5;
7. f(x)=1/√(0.02+0.01x); a=1; b=30;
8. f(x)=(1+2x+x2)/(5+2x2); a=-2; b=2;
9. f(x)=(2x+lg x)/(1+lg x); a=1; b=10;
10. f(x)=√(2+x)3/x2; a=0.2; b=10;
4. КОНТРОЛЬНЫЕ ВОПРОСЫ
-
Какой алгоритм является алгоритмом циклической структуры? -
Типы циклов в языке Си. -
Какой цикл выполнится хотя бы один раз? А какой - ни разу? -
Что такое массив? индекс элемента массива? -
Как ввести и вывести элементы вектора в строку и в столбец? -
Способы описания и инициализации массивов.
Лабораторная работа №3
Матрицы (двумерные массивы)
1. Цель работы: программирование алгоритмов обработки двумерных массивов
-
Основные сведения
Матрица – это прямоугольная таблица элементов (например, чисел или символов). Матрица представляется в виде двумерного массива, то есть массива, все элементы которого имеют два индекса. Матрица, как и таблица, состоит из строк и столбцов. Два индекса элемента - это и есть номера строки и столбца, на пересечении которых этот элемент находится. В языке Си каждый индекс записывается отдельно в квадратных скобках. Каждую строку и каждый столбец матрицы можно рассматривать как обычный одномерный массив. Поэтому можно сказать, что матрица – это массив из массивов.
Первый индекс элемента матрицы – это строка, второй – столбец. Поэтому когда говорят о «матрице 4 на 5», это означает, что матрица имеет 4 строки и 5 столбцов. Матрицы, у которых число строк равно числу столбцов, называют квадратными. В квадратных матрицах можно выделить главную диагональ – это все элементы, у которых номер строки равен номеру столбца, то есть A[0][0], A[1][1], ..., A[N-1][N-1] для матрицы размером N на N.
Объявление матриц
Матрицы объявляются так же, как и простые массивы, но у них не один индекс, а два. При объявлении в отдельных квадратных скобках указывается количество строк и количество столбцов. Например, оператор
int B[10][10];
выделит место в памяти под матрицу целых чисел, имеющую 10 строк и 10 столбцов. Если матрица глобальная (объявляется выше всех процедур и функций), то она в самом начале заполняется нулями. Локальные матрицы (объявленные внутри процедуры или функции) первоначально содержат «мусор» – неизвестные значения.
Начальные значения элементов
При объявлении можно сразу задать все или часть ее элементов, например:
float X[2][3] = {{1., 2., 3.},{4., 5., 6.}};
Как видно из примера, элементы каждой строки заключаются в отдельные фигурные скобки. Если задать не все элементы, то остальные заполнятся нулями:
float X[2][3] = {{1., 3.},{6.}};
Здесь элементы X[1][2], X[2][1] и X[2][2] будут нулевыми.
Расположение матриц в памяти
Во всех современных языках программирования элементы матрицы располагаются по строкам, то есть сначала изменяется последний индекс. Объявленная выше матрица X расположена так:
X[0][0] X[0][1] X[0][2] X[1][0] X[1][1] X[1][2]
Стандартный ввод и вывод
Для работы с матрицами требуется вложенный цикл, то есть цикл в цикле.
#include
const int M = 5; // число строк
const int N = 4; // число столбцов
main()
{
int i, j, A[M][N];
for ( i = 0; i < M; i ++ ) // цикл по строкам
for ( j = 0; j < N; j ++ ) // цикл по столбцам строки (элементы строки)
{
printf ("A[%d][%d]=", i, j); // подсказка для ввода
scanf ("%d", & A[i][j]); // ввод A[i][j]
}
// работа с матрицей
}
Заполнение случайными числами
Выполняется также в двойном цикле аналогично одномерным массивам. В примере показано заполнение целой матрицы случайными числами в интервале [a,b].
for ( i = 0; i < M; i ++ )
for ( j = 0; j < N; j ++ )
A[i][j] = random(b-a+1) + a;
Вывод на экран
При выводе матрицы ее элементы желательно расположить в привычном виде – по строкам, т.е. вывели одну строку матрицы, перешли на новую строку экрана, и т.д. Надо учитывать, что для красивого вывода на каждый элемент матрицы надо отвести равное количество символов (иначе столбцы будут неровные). Делается это с помощью форматирования – цифра после знака процента задает количество символов, отводимое на данное число.
printf("Матрица A\n");
for ( i = 0; i < M; i ++ ) // цикл по строкам
{
for ( j = 0; j < N; j ++ ) // вывод одной строки (в цикле)
printf ( "%4d", A[i][j] ); // 4 символа на число
printf("\n"); // переход на другую строку
}
Алгоритмы для работы с матрицами
1) Поиск минимального элемента
В отличие от одномерных массивов, для перебора всех элементов матрицы надо использовать двойной цикл. Ниже показано, как найти минимальный элемент в массиве и его индексы. Сначала считаем, что минимальным является элемент A[0][0], а затем проходим все элементы, проверяя, нет ли где еще меньшего. Можно запоминать только индексы, а значение минимального элемента получать прямо из массива.
float A[M][N], i, j, row, col;
...
row = col = 0; // сначала считаем, что A[0][0] - минимальный
for ( i = 0; i < M; i ++ ) // просмотр всех строк
for ( j = 0; j < N; j ++ ) // просмотр всех столбцов
if ( A[i][j] < A[row][col] )
{
row = i; // запомнили новые индексы
col = j;
}
printf ("Минимальный элемент A[%d][%d]=%d",row, col, A[row][col]);
2) Работа с отдельными элементами
Рассмотрим квадратную матрицу N на N. Выведем на экран обе ее диагонали (главную диагональ и перпендикулярную ей). С главной диагональю все просто – в цикле выводим все элементы, у которых номера строки и столбца равны, то есть A[i][i] для всех i от 0 до N-1.
Вторую диагональ формируют такие элементы:
A[0][N-1], A[1][N-2], A[2][N-3], ..., A[N-1][0]
Обратим внимание, что каждый следующий элемент имеет номер строки на 1 больше, а номер столбца – на 1 меньше. Таким образом, сумма номеров строки и столбца постоянна и равна N-1. Тогда, зная номер строки i можно сразу сказать, что на второй диагонали стоит ее элемент A[i][N-1-i].
3) Перестановка строк и столбцов
Пусть надо переставить две строки с индексами i1 и i2. Это значит, что для каждого столбца j надо поменять местами элементы A[i1][j] и A[i2][j] через временную переменную temp.
for ( j = 0; j < N; j ++ )
{
temp = A[i1][j];
A[i1][j] = A[i2][j];
A[i2][j] = temp;
}
Пример, объединяющий некоторые типовые алгоритмы работы с матрицей.
Даны две матрицы А и В одинакового размера m x n, заполненные случайными числами в диапазоне от 0 до 19. Получить матрицу C=max(A[i.j],B[i,j]) и матрицу D=min(A[i,j],B[i,j]).
#include
#include
#include
const int m=4, n=4;
int random(int r)
{ return rand()%r;
}
main()
{
int i,j,a[m][n],b[m][n],c[m][n],d[m][n];
system("CLS");
srand(11); //инициализация датчика случайных чисел
for(i=0;i
for(j=0;j
a[i][j]=random(20);
for(i=0;i
for(j=0;j
b[i][j]=random(20);
// вывод матриц а и b
printf("\n матрица a\n");
for (i=0;i
{ printf("\n");
for (j=0;j
printf("%4d",a[i][j]);
}
printf("\n\n матрица b\n");
for (i=0;i
{ printf("\n");
for (j=0;j
printf("%4d",b[i][j]);
}
// формирование матриц c и d
for (i=0;i
for (j=0;j
if (a[i][j]>b[i][j])
{ c[i][j]=a[i][j];
d[i][j]=b[i][j];
}
else
{ c[i][j]=b[i][j];
d[i][j]=a[i][j];
}
// вывод матриц c и d
printf("\n\n матрица c\n");
for (i=0;i
{ printf("\n");
for (j=0;j
printf("%4d",c[i][j]);
}
printf("\n\n матрица d\n");
for (i=0;i
{ printf("\n");
for (j=0;j
printf("%4d",d[i][j]);
}
puts("\n");
system("PAUSE");
}
-
Выполнение работы
1 2 3
Варианты задания (номер варианта определяется по последней цифре номера студенческого билета):
0. Сформировать двумерный массив A размером N x 2 (N - количество строк, равное предпоследней цифре номера студенческого билета+2 2 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. Найти наибольший элемент каждой строки матрицы А. Из этих максимальных элементов составить одномерный массив F. Вывести элементы массива F.
1. Сформировать двумерный массив B размером N x 3 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 3 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. Составить одномерный массив D из минимальных элементов столбцов матрицы. Вывести элементы массива D.
2. Сформировать двумерный массив B размером N x 4 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 4 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. Вычислить и вывести строку матрицы B, содержащую максимальное количество отрицательных.
3. Сформировать двумерный массив C размером N x 5 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 5 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. Вычислить сумму положительных элементов в каждой строке матрицы C . Из полученных сумм составить одномерный массив D. Вывести элементы массива D.
4. Сформировать двумерный массив D размером N x 6 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 6 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива на экран и в файл (см. п.3.4. и п.3.6.). В каждом столбце матрицы D найти максимальный элемент. Среди найденных чисел найти минимальное и вывести на экран и в файл.
5. Сформировать двумерный массив E размером N x 7 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 7 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. Вычислить сумму отрицательных элементов столбца, в котором находится максимальный элемент матрицы E. Вывести полученную сумму и номер столбца.
6. Сформировать двумерный массив F размером N x 8 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 8 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. В строке матрицы F, содержащей максимальный элемент, заменить все отрицательные числа на нули. Вывести номер этой строки и максимальный элемент.
7. Сформировать двумерный массив G размером N x 9 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 9 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. Записать в одномерный массив F строку матрицы G, содержащую минимальный элемент. Вывести элементы массива F.
8. Сформировать двумерный массив L размером N x 10 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 10 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. Вывести номер строки и саму строку матрицы L, в которой сумма положительных элементов максимальна.
9. Сформировать двумерный массив Z размером N x 11 (N – количество строк, равное предпоследней цифре номера студенческого билета +2 11 – количество столбцов) с помощью генератора случайных чисел и вывести элементы массива. Вычислить сумму положительных элементов строки, в которой находится минимальный элемент матрицы Z. Вывести полученную сумму и номер строки.
-
Контрольные вопросы
-
Как объявить матрицу? Как инициализировать? -
Ввод – вывод матрицы по строкам. -
Как поменять местами строки в матрице? -
Как найти минимальный элемент матрицы и его индексы? -
Как вычислить сумму элементов строки матрицы? -
Как получить транспонированную матрицу?
2 часть
Лабораторная работа № 4
Функции. Рекурсия.
1. ЦЕЛЬ РАБОТЫ: Изучение методов использования функций языка Си.
2. ОСНОВНЫЕ СВЕДЕНИЯ
Часто в программе требуется повторить определенную последовательность операторов в разных частях программы. Для того, чтобы описывать эту последовательность один раз, а применять многократно, в языках программирования применяются подпрограммы. Подпрограмма - автономная часть программы, выполняющая определенный алгоритм и допускающая обращение к ней из различных частей общей программы.
В языке Си существует один вид подпрограмм - функции. Каждая программа в своем составе должна иметь главную функцию main(), служащую точкой входа в программу. Кроме функции main(), в программу может входить произвольное число функций, выполнение которых инициализируется либо прямо, либо вызовами из функции main(). Каждая функция по отношению к другой является внешней. Для того, чтобы функция была доступной, необходимо, чтобы до ее вызова о ней было известно компилятору. Форма записи функции:
<тип > <имя функции>(<формальные параметры>){<тело функции >}
Если тип возвращаемого функцией значения не указан, то подразумевается int. Если с именем функции не связан результат, то нужно указать тип функции void. Параметры, записываемые в обращении к функции, называются фактическими; параметры, указанные в описании функции - формальными. Фактические параметры должны соответствовать формальным по количеству, порядку следования и типу. Объекты, объявленные вне функции, действуют в любой функции и называются глобальными. Объекты, объявленные в функции, действуют только в ней и называются локальными. В теле функции обычно присутствует оператор return <выражение>, определяющий возвращаемое функцией значение.
Все параметры функции, кроме массивов, передаются по значению, т.е. внутри функции создаются локальные копии параметров. Если необходимо передать саму переменную, а не её копию, то в функцию передаётся адрес этой переменной. Таким образом, через параметры можно передавать результат выполнения функции. То есть, параметры, с помощью которых результаты должны передаваться из функции в точку вызова, описываются как указатели. Вызов функции может быть оформлен в виде оператора, если с именем функции не связано возвращаемое значение, или в виде выражения, если возвращаемое значение связано с именем функции.
Прототип функции может указываться до вызова функции вместо описания функции для того, чтобы компилятор мог выполнить проверку соответствия типов аргументов и параметров. Прототип функции по форме такой же, как и заголовок функции. В конце него ставится «;».
Функции можно подключать с помощью директивы #include <имя файла>. Такие файлы с функциями удобно использовать в диалоговых программах с пользовательским меню, позволяющих выбрать один из режимов.
Пример 1: Функция с параметрами-значениями. Результат связан с именем функции. В программе объявляется прототип функции, а сама функция описывается ниже.
//lab8_1
#include
#include
int max(int,int); //Прототип функции
void main()
{ int x,y,z;
printf(" input x,y ");
scanf("%d%d",&x,&y);
z=max(x,y); //Вызов функции с фактическими параметрами
printf("x=%d y=%d max=%d",x,y,z);
getch();
}
int max(int a ,int b) //Заголовок функции с формальными параметрами
{ int c;
if (a>b) c=a;
else c=b;
return c;
}
Пример 2: Функция с параметрами-указателями. Здесь передаются адреса фактических параметров, по которым и получаем результат. Функция меняет местами переменные x,y.
//lab8_2
#include
#include
main()
{ float x,y;
void swap(float *, float *); // Прототип функции с параметрами - указателями
printf("\n введите x,y ");
scanf("%f%f",&x,&y);
swap(&x,&y); // Передаём адреса переменных
printf("\n x=%4.2f y=%4.2f ",x,y);
getch();
}
void swap(float * a, float * b)
{float c;
c=*a; // *a - содержимое по адресу a
*a=*b;
*b=c;
}
Пример 3: Подключение файлов с функциями и создание меню.
! Внимание! Следите за тем, чтобы константы, объявленные директивой #define, не переобъявлялись в функциях.
//lab8_3
#include
#include
#include "lab3.c"
#include "lab5.c"
#include "lab6.c"
main()
{ int nom;
while(1)
{ clrscr();
printf("\n 1. Сумма ряда \n");
printf(" 2. Матрица \n");
printf(" 3. Строки \n");
printf(" 4. Выход \n");
scanf("%d",&nom);
switch(nom)
{
case 1:lab3();break;
case 2:lab5();break;
case 3:lab6();break;
case 4:return 0;
default:printf("Неверный режим");
}
}
getch();
}
Пример 4: Передача в функцию массива с использованием указателя. Результат – элементы массива возводятся в квадрат. Функция описывается до вызова, поэтому прототип не объявляется.
//lab8_4
#include
#include
void quart(int n, float * x) // Можно void quart(int n, float x[])
{ int i;
for (i=0;i
x[i]=x[i]*x[i];
}
main()
{ float z[]={1,2,3,4};int j;
clrscr();
for (j=0;j<4;j++)
printf(" %6.2f",z[j]);
quart(4,z);
for (j=0;j<4;j++)
printf("\n %6.2f",z[j]);
getch();
}
В языке Си функции могут вызывать сами себя, т.е. обладать свойством рекурсивности. Рекурсивная функция обязательно должна содержать в себе условие окончания рекурсивности, чтобы не вызвать зацикливания программы. При каждом рекурсивном вызове создается новое множество локальных переменных. Т.о. переменные, расположенные вне вызываемой функции, не изменяются.
Пример. Составить рекурсивную функцию, вычисляющую факториал числа n следующим образом: n!= 1 , если n<= 1 и n!= ( n -1 )! · n, если n > 1
long fact( int n)
{ if (n <=1) return l;
else return (n * fact ( n -1 )); // функция fact вызывает саму себя
}
Таким образом, последовательно вызываются функции f(n), f(n-1),f(n-2)…f(1).
Достоинством рекурсий является компактная запись, а недостатком – расход времени и памяти на повторные вызовы функции и передачу ей копий параметров.
3. ВЫПОЛНЕНИЕ РАБОТЫ
Используя функции, написать программу по своему варианту.
Варианты заданий
1. Написать функцию, выводящую в порядке возрастания элементы одномерного массива. В главной программе вызвать функцию для двух разных массивов.
2. Написать функцию вычисления произведения прямоугольной матрицы A размера k x m на прямоугольную матрицу B размера m x n. В главной программе обратиться к этой функции.
3. Написать функцию вычисления суммы ряда s=s(1)+…+s(n),
где s(n)=(-1)n x(2n-1)/(2n+1) с точностью до eps=0.001. В качестве параметров выбрать x и eps.
4. Написать функцию, которая вычисляет для заданной квадратной матрицы A её симметричную часть S(ij)=(A(ij)+A(ji))/2 и кососимметричную часть K(ij)=(A(ij)-A(ji))/2.
5. Написать функцию “шапочка” f(x), зависящую от параметров a и b: если |x| >a то f(x)=0 иначе f(x)=b*exp(-a2/(a2-|x|2)). В качестве параметров передать a,b,x.
6. Написать функцию поиска максимального и минимального элементов одномерного массива. В основной программе вызвать эту функцию для двух разных массивов.
7. Написать функцию, которая сортирует одномерный массив в порядке убывания методом пузырька. В основной программе вызвать эту функцию для двух разных массивов.
8. Написать функцию, которая по двум заданным одномерным массивам (A размера m и B размера n) вычисляет максимальное значение двумерного массива c(ij)=a(i)*b(j).
9. Написать функцию вычисления суммы ряда y=x-x/2!+…
+(-1)n+x/n! с точностью до eps=0.001. В качестве параметров передать x (в радианах) и eps.
10. Написать функцию вычисления ряда y=x+x3/3!+…+x2n+1/(2n+1)! с точностью до eps=0.0001. В качестве параметров передать x и eps.
11. Написать функцию обработки матриц A и B одинакового размера m x n. Получить матрицу C =max(a(i,j),b(i,j)), и матрицу D=min(a(i,j),b(i,j)). Матрицы C и D вывести в главной программе.
4. КОНТРОЛЬНЫЕ ВОПРОСЫ
4.1. Описание функции. Для чего объявляется прототип?
4.2. Что такое формальные и фактические параметры? Локальные и глобальные?
4.3. Как можно передавать массив в функцию?
4.4. Способы вызова функций.
Лабораторная работа № 5
Динамические массивы
1. ЦЕЛЬ РАБОТЫ: приобретение практических навыков создания и обработки одномерных и многомерных динамических массивов.
2. ОСНОВНЫЕ ПОНЯТИЯ
При определении статического массива: тип имя_массива [количество_элементов] , имя_массива становится указателем на область памяти, выделяемой для размещения элементов массива. Количество элементов должно быть константой. Таким образом, размеры памяти, выделяемой под массив, заданы в определении массива. Но иногда нужно, чтобы размеры памяти были не фиксированными, а выделялись в ходе выполнения программы при решении конкретной задачи.
Формирование массивов с переменными размерами можно организовать с помощью указателей и средств для динамического выделения памяти. Эти средства описаны в файле
int *p;
p=(int *)malloc(size); //Указателю на целое p присваивается адрес начала выделенной области памяти размером size байт.
p=(int *)calloc(n, size); //Указателю на целое p присваивается адрес начала выделенной области памяти размером n*size байт.
free(p); //Освобождает выделенную по адресу p память. Преобразование указателя любого типа к типу void * осуществляется автоматически, так что в качестве фактического параметра можно подставить указатель любого типа без явного приведения типов.
Пример формирования одномерного динамического массива
#include
#include
#include
main()
{ float *p,d;
int i,n;
printf("\n input n:");
scanf("%d",&n);
p=(float *)malloc(n*sizeof(float));
for (i=0;i
{printf("x[%d]=",i);
scanf("%f",&d);
p[i]=d;
}
for (i=0;i
{ if (i%4==0) printf("\n");
printf("\t x[%d]=%6.2f",i,p[i]);
}
free(p);
getch();
}
Доступ к участкам выделенной памяти выполняется с помощью операции индексирования: p[i].
Каждый элемент массива может быть, в свою очередь, массивом. Именно так конструируются динамические многомерные массивы. Рассмотрим алгоритм создания и обработки двумерного массива.
-
Определяем указатель на массив указателей , задающий адреса начала строк матрицы: тип **uk. -
Вводим размеры матрицы n,m. -
Создаём динамический массив указателей на указатели начала строк : uk=(тип **)malloc(n*sizeof(тип *)); -
В цикле выделяем память под n массивов – строк по m элементов в каждом: for (i=0;i -
Обработка массива (работа с индексированными элементами uk[i][j]). -
В цикле освобождаем память, занятую под n массивов – строк : for (i=0;i -
Освобождаем память, занятую под массив указателей : free(uk).
Пример обработки двумерного динамического массива
Составить программу, создающую динамическую матрицу размером n*n, заполнить матрицу случайными числами. Вычислить сумму каждой строки и поместить суммы строк в одномерный динамический массив.
//lab11_2
#include
#include
#include
#include
void main()
{ int n,j,i;
float ** matr; float * mass; // Объявляем matr - указатель на массив указателей и //mass – указатель на одномерный массив
clrscr();
printf("Введите размер квадратной матрицы n: "); scanf("%d",&n);
mass=(float *)malloc(n*sizeof(float )); // Выделяем память под одномерный массив
if (mass==NULL)
{ puts("не создан динамический массив!");
return;}
matr=(float **)malloc(sizeof(float *)*n); //Выделяем память под массив указателей
if (matr==NULL)
{ puts("не создан динамический массив!");
return;}
randomize();
for (i=0;i
{ matr[i]=(float *)malloc(sizeof(float)*n); // Выделяем память под i-ю строку
if (matr[i]==NULL)
{ puts("не создан динамический массив!");
return;}
for (j=0;j
}
for (i=0;i
{ mass[i]=0;
for (j=0;j
mass[i]+=matr[i][j];
}
for (i=0;i
{ for (j=0;j
printf("\t%6.2f",matr[i][j]);
printf("\n");
}
for (i=0;i
printf("\n сумма %d строки %8.2f",i,mass[i]);
for (i=0;i
free(matr[i]); //Освобождаем память i – й строки
free(matr); // Освобождаем память массива указателей
free(mass); // Освобождаем память массива сумм
getch();
}
3. ВЫПОЛНЕНИЕ РАБОТЫ
3.1. Проанализировать приведенные программы.
3.2. Создать двумерный динамический массив и выполнить задание по своему варианту.
Варианты заданий
1. Даны матрица A размером m*n и вектор В размером m. Записать на главную диагональ элементы вектора, а в вектор - элементы главной диагонали.
2. Выбрать максимальный элемент матрицы С (размер m*n), элементы четных строк разделить на максимальный элемент, а к элементам нечетных прибавить максимальный элемент.
3. Найти минимальный элемент матрицы С (размер m*n), и поменять его местами с первым элементом.
4. Дана матрица Е размером m*n. Вычислить суммы элементов каждого столбца. Определить наибольшее значение этих сумм и номер соответствующего столбца.
5. В матрице К размером m*n найти в каждом столбце произведение отрицательных элементов и количество нулевых элементов в матрице .
6. Даны две матрицы А и В одинаковой размерности m*n. Получить матрицу
C = max (a i j, b i j ), и матрицу D = min (a i j, b i j).
7. Дана матрица Р размером m*n . Найти сумму минимальных элементов каждого столбца матрицы.
8. Даны матрицы: А размером m*k и В размером k*n.Получить матрицуС=A*В.
9. Дана матрица К размером m*n. Вычислить сумму минимальных элементов каждого столбца.
10. Дана матрица С размером m*n. Упорядочить эту матрицу по возрастанию элементов в каждом столбце.
4. КОНТРОЛЬНЫЕ ВОПРОСЫ
4.1. Отличия динамического массива от статического.
4.2. Как создать одномерный динамический массив?
4.3. Как создать динамическую матрицу?
4.4. Как освобождается память, занятая под динамические структуры?
Лабораторная работа № 6
Обработка бинарных файлов
1. ЦЕЛЬ РАБОТЫ: приобретение практических навыков создания и обработки бинарных файлов.
2. ОСНОВНЫЕ ПОНЯТИЯ
Файл - это упорядоченная последовательность однотипных компонентов, расположенных на внешнем носителе. Файлы предназначены только для хранения информации, а обработка этой информации осуществляется программами. Использование файлов целесообразно в случае:
-
долговременного хранения данных; -
доступа различных программ к одним и тем же данным; -
обработки больших массивов данных, которые невозможно целиком разместить в оперативной памяти компьютера.
Файл, не содержащий ни одного элемента, называется пустым. Создается файл путем добавления новых записей в конец первоначально пустого файла. Длина файла, т.е. количество элементов, не задается при определении файла. При вводе и выводе данные рассматриваются как поток байтов. Физически поток – это файл или устройство (клавиатура или дисплей). В Си поток можно открыть для чтения и/или записи в текстовом или бинарном (двоичном) режиме. В текстовых файлах не употребляются первые 31 символ кодовой таблицы ASCII (управляющие), а символы конца строки 0x13 (возврат каретки, CR) и 0x10 (перевод строки LF) преобразуются при вводе в одиночный символ перевода строки \n (при выводе выполняется обратное преобразование). Эти символы добавляются в конце каждой строки, записываемой в текстовый файл. При обнаружении в текстовом файле символа с кодом 26 (0x26), т.е. признака конца файла, чтение файла в текстовом режиме заканчивается, хотя файл может иметь продолжение.
В двоичном режиме эти преобразования не выполняются, чтение продолжается, пока не встретится физический конец файла. При чтении символы не преобразуются и не анализируются.
Функция открытия потока fopen возвращает указатель на предопределенную структуру типа FILE (содержащую всю необходимую для работы с потоком информацию) при успешном открытии потока, или NULL в противном случае.
В заголовочном файле stdio.h содержится описание файлового типа FILE, с которым связывается файловая переменная (указатель на файл). При открытии файла указатель на файл связывается с конкретным файлом на диске и определяется режим открытия файла:
r (r+) - файл открывается для чтения (чтения и записи);
w (w+) - открывается пустой файл для записи (чтения и записи). Если файл с таким именем существует, он стирается;
a (а+)- файл открывается для дополнения в конец (чтения и дополнения).
Режим открытия может также содержать символы t (текстовый файл) и b (двоичный файл), указывающий на вид открываемого файла: rb, wb, ab, rt, at, rb+, wb+, ab+ и т.д.
Закрытие файла (текстового или бинарного) выполняется функцией fclose(), установка указателя на начало файла - функцией rewind(). Если при попытке чтения данных из файла встречается символ конца файла, то возвращается специальное значение EOF. Функции feof(),ferror() сообщают о причинах, по которым операция ввода/вывода не выполнилась.
Если файл открыт в бинарном режиме, его можно записывать или считывать побайтно. Функция fseek() позволяет обращаться с файлом как с массивом и переходить к любой позиции в файле, обеспечивая возможность произвольного доступа. Если текстовые файлы являются файлами с последовательным доступом, то произвольный доступ чаще всего применяется к бинарным файлам.
Бинарные файлы могут содержать любую информацию. Чаще всего используются файлы, содержащие структуры. Для чтения и записи в бинарные файлы можно использовать функции fread(), fwrite() или fscanf(),fprintf().
fread –функция для чтения из файла:
int fread(void *ptr, unsigned size, unsigned count, FILE *f);
Из файла f считываются и по адресу ptr записываются count элементов размером size каждый. Функция возвращает число фактически считанных элементов.
fwrite – функция для записи в файл:
int fwrite(void *ptr, unsigned size, unsigned count, FILE *f);
В файл записываются, начиная с адреса ptr, count элементов размером size каждый. Функция возвращает число фактически записанных элементов.
fseek – функция для произвольного доступа к байтам бинарных файлов:
int fseek(FILE *f, long offset, int w);
offset показывает, на сколько байт нужно сместиться относительно точки отсчёта – w.
w должно быть равно одной из трех констант:
SEEK_SET или 0 - начало файла;
SEEK_CUR или 1 – текущая позиция в файле;
SEEK_END или 2 – конец файла.
ftell - возвращает текущую позицию в файле как длинное целое:
long int ftell (FILE *f);
1 2 3
Пример обработки бинарного файла
Составить программу, выполняющую следующие функции:
-
Создание нового файла; -
Просмотр файла; -
Добавление информации в конец файла; -
Поиск по названию товара и изменение цены и количества;
Файл создать из структур вида: название товара, его цена и количество.
Задание выполнить в отдельных функциях. Использовать меню для выбора функций.
//lab10_1
#include
#include
#include
struct tov {char name[10]; float c; int kol;} t1;
void input(FILE *); // создание нового файла
void print(FILE *); // просмотр файла
void app(FILE *); // добавление в файл
void find(FILE *); // поиск и изменение
main()
{ char c;
FILE *tf;
while (1)
{ clrscr();
puts(" 1 – новый файл");
puts(" 2 – просмотр файла");
puts(" 3 – добавление в файл");
puts(" 4 – поиск и изменение");
puts(" 0 - выход");
c=getch();
switch(c)
{ case '1':input(tf);break;
case '2':print(tf);break;
case '3':app(tf);break;
case '4':find(tf);break;
case '0':return 0;
default : puts(" неверный режим");
}
}
}
void input(FILE *tf)
{ char ch;
tf=fopen("file1.dat","wb"); // открытие бинарного файла для записи
clrscr();
printf("\n Ввод товаров\n");
do
{ printf("\n название: "); scanf("%s",&t1.name);
printf(" цена: "); scanf("%f",&t1.c);
printf(" количество: "); scanf("%d",&t1.kol);
fwrite(&t1,sizeof(t1),1,tf); // запись в файл одной структуры t1
printf("\n Закончить? y/n ");
ch=getch();
}
while (ch != 'y');
fclose(tf);
}
void print(FILE *tf)
{ int i;
clrscr();
tf=fopen("file1.dat","rb"); // открытие бинарного файла для чтения
i=1;
fread(&t1,sizeof(t1),1,tf); // чтение из файла одной структуры t1
while (!feof(tf))
{ printf("\n %3d tovar %10s cena %6.2f kolic %4d",i,t1.name,t1.c,t1.kol);
fread(&t1,sizeof(t1),1,tf);
i++;
}
getch();
}
void app(FILE *tf)
{ char ch;
tf=fopen("file1.dat","ab"); // открытие бинарного файла для добавления
clrscr();
printf("\n Ввод товаров \n");
do
{ printf("\n название: "); scanf("%s",&t1.name);
printf(" цена: "); scanf("%f",&t1.c);
printf(" количество: "); scanf("%d",&t1.kol);
fwrite(&t1,sizeof(t1),1,tf);
printf(" Закончить? y/n ");
ch=getch();
}
while (ch != 'y');
fclose(tf);
}
void find(FILE *tf)
{ char c,tov[10];
long int i;
tf=fopen("file1.dat","rb+"); // открытие бинарного файла для чтения и записи
clrscr();
puts(" Название искомого товара: ");
gets(tov);
fread(&t1,sizeof(t1),1,tf);
while (!feof(tf))
{ if (strcmp(t1.name,tov)==0)
{ printf(" tovar %10s cena %6.2f kolic %d",t1.name,t1.c,t1.kol);
printf("\n изменить? y/n ");
c=getch();
if (c=='y')
{ printf("\n количество: ");scanf("%d",&t1.kol);
printf("\n цена: ");scanf("%f",&t1.c);
i=sizeof(t1);
fseek(tf,-i,1); // возврат на sizeof(t1) байт назад
fwrite(&t1,sizeof(t1),1,tf); // запись изменённой структуры на прежнее место
}
}
fread(&t1,sizeof(t1),1,tf);
}
fclose(tf);
}
3. ВЫПОЛНЕНИЕ РАБОТЫ
3.1. Проанализировать приведенную программу.
3.2. Используя функции и режим меню, создать файл из 10 записей, просмотреть файл, добавить в файл новую информацию и, применяя режим прямого доступа, выполнить задание по своему варианту.
Варианты заданий
1. Запись имеет вид: фамилия, пол, год рождения и рост. Вывести данные о самом высоком спортсмене.
2. Запись имеет вид: название вуза, число студентов, количество факультетов. Добавить в конец файла информацию о трех новых вузах и посчитать общее число студентов.
3. Запись имеет вид: название издания, газеты или журнала, стоимость одного экземпляра, количество экземпляров в год. Вывести на печать информацию о самом дешевом издании.
4. Запись имеет вид: фамилия студента, номер зачетной книжки, 4 оценки за экзамен. Выводить информацию о всех двоечниках и корректировать ее.
5. Запись имеет вид: фамилия спортсмена, его номер, количество набранных очков. Поменять местами в файле записи о первых двух спортсменах. *
6. Запись имеет вид: фамилия, номер телефона, дата рождения. Внести в начало списка информацию о четырех новых знакомых.
7. Запись имеет вид: название инструмента, число, месяц и год изготовления. Вывести на печать информацию об инструменте с самым большим сроком использования и выполнить корректировку этой записи.
8. Запись имеет вид: номер читательского билета, автор книги, название, дата заказа. Вывести на экран содержимое файла. Поменять местами первую и последнюю записи в файле.
9. Запись имеет вид: фамилия спортсмена, его номер, количество набранных очков. Удалить из списка информацию о спортсмене с наименьшим количеством очков.
10. Запись имеет вид: фамилия, количество вещей, общий вес. Удалите из файла сведения о багаже, общий вес вещей в котором меньше, чем 10 кг.
4. КОНТРОЛЬНЫЕ ВОПРОСЫ
-
Чем отличается файл от массива? -
Что понимается под чтением, и что под записью в файл? -
Режимы доступа к файлам. -
Назначение функций fseek, ftell.
Привести пример корректировки К-той записи в файле прямого доступа
Список литературы
-
Баженова И.Ю. Введение в программирование [Электронный ресурс]: учебное пособие/ Баженова И.Ю., Сухомлин В.А.— Электрон. текстовые данные.— М.: БИНОМ. Лаборатория знаний, Интернет-Университет Информационных Технологий (ИНТУИТ), 2007.— 326 c.— Режим доступа: http://www.iprbookshop.ru/22400.— ЭБС «IPRbooks» -
Борисенко В.В. Основы программирования [Электронный ресурс]/ Борисенко В.В.— Электрон. текстовые данные.— М.: Интернет-Университет Информационных Технологий (ИНТУИТ), 2016.— 323 c.— Режим доступа: http://www.iprbookshop.ru/52206.— ЭБС «IPRbooks» -
Поляков А.Ю. Программирование [Электронный ресурс]: практикум/ Поляков А.Ю., Полякова А.Ю., Перышкова Е.Н.— Электрон. текстовые данные.— Новосибирск: Сибирский государственный университет телекоммуникаций и информатики, 2015.— 55 c.— Режим доступа: http://www.iprbookshop.ru/55494.— ЭБС «IPRbooks» -
Устинов В.В. Основы алгоритмизации и программирование. Часть 2 [Электронный ресурс]: конспект лекций/ Устинов В.В.— Электрон. текстовые данные.— Новосибирск: Новосибирский государственный технический университет, 2013.— 32 c.— Режим доступа: http://www.iprbookshop.ru/44675.— ЭБС «IPRbooks»
1 2 3