
- •Г.В. Ваныкина, т.О. Сундукова
- •Часть 1. Введение в программирование Тула - 2009
- •Содержание
- •Предисловие
- •Лабораторная работа №1
- •Лабораторная работа №2 Типы данных. Стандартные потоки ввода-вывода данных
- •Лабораторная работа №3 Константы. Стандартные потоки ввода-вывода вещественных данных
- •Лабораторная работа №4 Форматированный ввод-вывод данных
- •Лабораторная работа №5 Присваивание. Арифметические операции
- •Лабораторная работа №6 Логические и поразрядные операции. Операции сравнения и определения размера
- •Лабораторная работа №7 Математические функции. Выражения
- •Математические функции – файл math.H
- •Лабораторная работа №8 Линейные программы. Преобразование типов
- •Лабораторная работа №9 Операторы выбора: оператор условия if
- •Лабораторная работа №10 Решение задач с использование оператора условия if
- •Лабораторная работа №11 Операторы перехода. Операторы выбора: оператор-переключатель switch
- •Лабораторная работа №12 Решение задач с использованием оператора-переключателя switch
- •Лабораторная работа №13 Операторы цикла: оператор цикла с параметром for
- •Лабораторная работа №14 Операторы цикла: оператор цикла с предусловие while
- •Лабораторная работа №15 Операторы цикла: оператор цикла с постусловием do … while
- •Лабораторная работа №16 Решение задач с использованием операторов цикла
- •Лабораторная работа №17 Функции пользователя
- •Лабораторная работа №18 Решение задач методом процедурной абстракции
- •Лабораторная работа №19 Рекурсивные функции
- •Индивидуальные задания Требования к оформлению индивидуальных заданий
- •Задание 1. Линейные программы
- •Задание 2. Задачи на составление логических выражений
- •Задание 3. Условный оператор
- •Задание 4. Цикл с параметром
- •Задание 5. Циклы с условиями
- •Задание 6. Числовые функции
- •Задание 7. Функции
- •Задание 8. Рекурсия
- •Литература
- •Часть 1. Введение в программирования
Лабораторная работа №18 Решение задач методом процедурной абстракции
Цель работы: научиться применять при разработке программ метод процедурной абстракции с использованием функций пользователя на языке C++.
Теоретические сведения
Метод процедурной абстракции
При структурном программировании решение задачи осуществляется методом процедурной абстракции (иначе говоря «сверху вниз»). При этом задача разбивается на подзадачи, а решение оформляется в основной программе в виде последовательности вызовов подзадач. После разработки общей схемы решения каждая подзадача оформляется в виде независимой подпрограмм.
Функции помогают применять для разработки программ структурный метод проектирования «сверху вниз». При этом решаемая задача делится на подзадачи (и затем на под-подзадачи и т.д.). Для решения каждой подзадачи программист реализует отдельную функцию, при этом ему не нужно знать детали реализации остальных функций.
Чтобы функцией мог воспользоваться другой программист, она должна иметь осмысленное имя и комментарий с описанием назначения функции, ее параметров и возможных возвращаемых значений.
Опытные программисты на начальных этапах разработки часто применяют пустые функции (заглушки), которые содержат только оператор возврата значения соответствующего типа. Эти функций облегчают отладку главной функции или просто функции более высокого уровня.
Выделение в решаемой задаче функций методом «сверху вниз» часто называется функциональной или процедурной абстракцией. При проектировании независимых друг от друга функций широко применяется передача параметров по значению и локальные переменные внутри функций. После реализации программист может рассматривать подобные функции как «черные ящики». Для их использования знать детали реализации не обязательно.
Помимо метода «сверху вниз», вторым важным методом структурного проектирования является метод модульного программирования. Он предполагает разделение текста программы на несколько файлов, в каждом из которых сосредоточены независимые части программы (сгруппированные по смыслу функции).
Передача значений функций
Основным способом обмена информацией между вызываемой и вызывающей функциями являются механизм параметров. Существует два способа передачи параметров в функцию: по адресу и по значению.
При передаче по значению выполняются следующие действия:
вычисляются значения выражений, стоящие на месте фактических параметров;
в стеке выделяется память под формальные параметры функции;
каждому фактическому параметру присваивается значение формального параметра, при этом проверяются соответствия типов и при необходимости выполняются их преобразования.
Например:
double square(double a, double b, double c) {
/*функция возвращает площадь треугольника, заданного длинами сторон а,b,c*/
double s, p=(a+b+c)/2;
return s=sqrt(p*(p-a)*(p-b)*(p-c));//формула Герона
}
1) double s1=square(2.5,2,1);
2) double a=2.5,b=2,c=1;
double s2=square(a,b,c);
3) double x1=1,y1=1,x2=3,y2=2,x3=3,y3=1;
double s3=square(
sqrt(pow(x1-x2,2)+pow(y1-y2,2)),//расстояние между 1 и 2
sqrt(pow(x1-x3,2)+pow(y1-y3,2)),//расстояние между 1 и 3
sqrt(pow(x3-x2,2)+pow(y3-y2,2)));//расстояние между 2 и3
Таким образом, в память заносятся копии фактических параметров, и операторы функции работают с этими копиями. Доступа к самим фактическим параметрам у функции нет, следовательно, нет возможности их изменить.
При передаче по адресу в память заносятся копии адресов параметров, следовательно, у функции появляется доступ к ячейке памяти, в которой находится фактический параметр и она может его изменить.
Например:
void Change(int a,int b) { //передача по значению
int r=a; a=b; b=r;
}
int x=1,y=5;
Change(x,y);
cout << ”x=” << x << ”y=” << y;
выведется: x=1 y=5
void Change(int *a,int *b) { //передача по адресу
int r=*a; *a=*b; *b=r;
}
int x=1,y=5;
Change(&x,&y);
cout << ”x=” << x << ”y=” << y;
выведется: x=5 y=1
Для передачи по адресу также могут использоваться ссылки. При передаче по ссылке в функцию передается адрес указанного при вызове параметра, а внутри функции все обращения к параметру неявно разыменовываются.
void Change(int &a,int &b){
int r=a; a=b; b=r;
}
int x=1,y=5;
Change(x,y);
cout << ”x=” << x << ”y=” << y;
выведется: x=5 y=1
Использование ссылок вместо указателей улучшает читаемость программы, т.к. не надо применять операцию разыменовывания. Использование ссылок вместо передачи по значению также более эффективно, т.к. не требует копирования параметров. Если требуется запретить изменение параметра внутри функции, используется модификатор const. Рекомендуется ставить const перед всеми параметрами, изменение которых в функции не предусмотрено (по заголовку будет понятно, какие параметры в ней будут изменяться, а какие нет).
Пример 1. Для данных трех натуральных чисел найдите их НОД. Разработайте функцию нахождения НОД двух чисел.
#include <stdio.h>
long NOD (long x,long y);
void main (){
long a,b,c,z;
printf("Введите первое число = ");
scanf("%ld",&a);
printf("Введите второе число = ");
scanf("%ld",&b);
printf("Введите третье число = ");
scanf("%ld",&c);
z=NOD(c,NOD(a,b));
printf("Наибольший общий делитель 3 чисел равен %ld",z);
}
long NOD(long x,long y){
long x1,y1;
while (y!=0){
x1=y;
y1=x%y;
x=x1;
y=y1;
}
return x;
}
Задания
Для решения задач используйте метод процедурной абстракции
Дано натуральное число n. Найти все меньшие n числа Мерсена. Простое число называется числом Мерсена, если оно может быть представлено в виде
где p – тоже простое число. Например, 31=25–1 – число Мерсена.
Для данных k натуральных чисел найдите их НОД. Разработайте функцию нахождения НОД двух чисел.
Два простых числа называются «близнецами», если они отличаются друг от друга на 2 (например, 41 и 43). Напечатать все пары «близнецов» из отрезка [n, 2n], где n – заданное натуральное число, большее 2.
Вычислите результат выражения
в виде обыкновенной дроби, где A, B, C, E, F – целые числа. Разработайте функции сложения и умножения двух дробей, а также функцию сокращения дроби.
Домашние задания
Для данного натурального N найдите сумму факториалов: 1! + 2! + 3! + … + N!
Имеется кусок льда массой Мl при температуре 0оС, который нагревается за счет сжигания каменного угля массой Mu (потерями энергии пренебречь). Определите агрегатное состояние нагреваемого вещества после полного сгорания угля. Физические величины следует взять из справочника и оформить как константы.
Индивидуальное задание. Номер варианта определяется по журналу. Составьте программу для решения задачи.
Варианты индивидуального задания
№ |
Задание |
|
Даны основания и высоты двух равнобедренных трапеций. Найти сумму их периметров. Определите функцию для расчета периметра равнобедренной трапеции по ее основаниям и высоте. |
|
Найдите сумму первых n чисел последовательности Фибоначчи. Разработайте функцию нахождения k-го числа последовательности Фибоначчи. |
|
Дана квадратная матрица размерности 33. Найдите ее определитель. Разработайте функцию вычисления определителя второго порядка. |
|
Описать функцию DigitN(K, N) целого типа, возвращающую N-ю цифру целого положительного числа K (цифры в числе нумеруются справа налево). Если количество цифр в числе K меньше N, то функция возвращает –1. |
|
Описать функцию Exp1(x, ε) вещественного типа (параметры x, ε – вещественные, ε > 0), находящую приближенное значение функции exp(x): exp(x) = 1 + x + x2/(2!) + x3/(3!) + … + xn/(n!) + … В сумме учитывать все слагаемые, большие ε. С помощью Exp1 найти приближенное значение экспоненты для данного x при заданном ε. |
|
Описать функцию Sin1(x, ε) вещественного типа (параметры x, ε — вещественные, ε > 0), находящую приближенное значение функции sin(x): sin(x) = x – x3/(3!) + x5/(5!) – … + (–1) n·x2n+1/((2n+1)!) + … . В сумме учитывать все слагаемые, модуль которых больше ε. С помощью Sin1 найти приближенное значение синуса для данного x при заданном ε. |
|
Даны вещественные числа x1,y1,x2,y2,…x5,y5. Найти площадь пятиугольника, вершины которого имеют координаты (x1,y1), (x2,y2), …, (x5,y5). Разработайте функции для определения существования пятиугольника и расчета площади треугольника по координатам его вершин. |
|
Описать функцию IsPalindrom(K), возвращающую True, если натуральный параметр K является палиндромом (то есть его запись читается одинаково слева направо и справа налево), и False в противном случае. С ее помощью найти количество палиндромов на заданном отрезке [a,b]. |
|
На отрезке с натуральными границами [a,b] найдите все полные квадраты. Определите функцию, позволяющую распознать, является ли данное число полным квадратом. Натуральное число является полным квадратом, если оно является квадратом натурального числа. Например, 36 – полный квадрат, так как 62=36. |
|
Даны два натуральных числа. Выяснить, в каком из них произведение цифр больше. Определите функцию для расчета произведения цифр натурального числа. |
|
Найдите все натуральные трехзначные числа из отрезка [a, b], сумма квадратов цифр которых равна заданному натуральному k. Разработайте функцию подсчета суммы квадратов цифр трехзначного числа. |
|
Описать функцию Cos1(x, ε) вещественного типа (параметры x, ε – вещественные, ε > 0), находящую приближенное значение функции cos(x): cos(x) = 1 – x2/(2!) + x4/(4!) – … + (–1)n x2n/((2·n)!) + … . В сумме учитывать все слагаемые, модуль которых больше ε. С помощью Cos1 найти приближенное значение косинуса для данного x при заданном ε. |
|
На отрезке с натуральными границами [a,b] найдите все степени пятерки. Определите функцию, позволяющую распознать, является ли данное число степенью пятерки. |
|
Два простых числа называются «близнецами», если отличаются дуг от друга на 2 (таковы, например, числа 41 и 43). Напечатать все пары чисел-«близнецов», не превышающих число 200. Определите функцию, позволяющую распознать простые числа. |
|
Даны два натуральных числа. Выяснить, в каком из них сумма цифр больше. Определите функцию для расчета суммы цифр натурального числа. |
|
Найдите сумму двойных факториалов чисел до данного натурального n включительно. Разработайте функцию вычисления двойного факториала натурального числа. |
|
Описать функцию NOD2(A, B) целого типа, находящую наибольший общий делитель (НОД) двух целых положительных чисел A и B, используя алгоритм Евклида: НОД(A, B) = НОД(B, A mod B), если B ≠ 0; НОД(A, 0) = A. С помощью этой функции найти наибольший среди наибольших общих делителей пар (A, B), (A, C), (С, D), если даны числа A, B, C, D. |
|
Описать функцию sign(X) целого типа, возвращающую для вещественного числа X следующие значения:
С помощью этой функции найти значение выражения (sign (A) + sign (B)) · sign (A–B) для данных вещественных чисел A и B. |
|
Учитывая, что наименьшее общее кратное двух целых положительных чисел A и B равно A · B / НОД(A, B), где НОД(A, B) — наибольший общий делитель A и B, опишите функцию NOK2(A, B) целого типа, находящую наименьшее общее кратное чисел A и B. С помощью NOK2 найти наименьшее среди наименьших общих кратных пар (A, B), (A, C), (В, D), если даны числа A, B, C, D. |
|
Описать функцию IsLeapYear(Y) логического типа, которая возвращает True, если натуральное Y является номером високосного года, и False в противном случае. Вывести все високосные года из временного промежутка [a, b]. Високосным считается год, делящийся на 4, за исключением тех годов, которые делятся на 100 и не делятся на 400. |
|
Разложите заданное натуральное число n на простые множители. Разработайте функцию определения простого числа. Например, для числа 120 ответом должна быть последовательность: 2 2 2 3 5. |
|
Составьте программу вывода на экран и подсчета количества всех натуральных чисел, меньших М, квадрат суммы цифр которых равен X. |
|
Составьте программу вывода на экран и подсчета количества всех натуральных чисел, не превосходящих N и делящихся на каждую из своих цифр. |
|
Напишите программу вычисления суммы квадратов простых чисел, лежащих в интервале (M, N). |
|
Составьте программу вычисления суммы трехзначных чисел, в десятичной записи которых нет четных цифр. |
|
Даны натуральные m и n (m<n). Составить программу, сокращающую дробь m/n. |
|
Определите, в какой сотне больше простых чисел. Рассмотрите сотни со второй до десятой. |
|
В пространстве даны три некомпланарных вектора своими координатами. Найдите площадь поверхности параллелепипеда, построенного на этих векторах. Разработайте функцию вычисления площади параллелограмма, построенного на двух векторах. |