- •Введение
- •1. Основы алгоритмизации и программирования
- •1.1. Этапы подготовки и решения задач на эвм
- •1.2. Алгоритмы и способы их описания Понятие алгоритма
- •Способы описания алгоритмов
- •Структурные схемы алгоритмов
- •1.3. Компиляция и интерпретация программ
- •1.4. Стили программирования
- •Процедурное программирование
- •Функциональное программирование
- •Логическое программирование
- •Объектно-ориентированное программирование
- •2.1. Пример готовой программы.
- •2.2. Структура основной программы
- •2.3. Алфавит языка
- •2.4. Константы и переменные Константы
- •Переменные
- •Примеры записи имен переменных
- •2.5. Арифметические выражения
- •Примеры вычисления арифметических выражений
- •Стандартные функции
- •Примеры программирования арифметических выражений
- •Контрольные задания
- •1. Составить описания для заданных переменных
- •2.6. Линейные вычислительные процессы
- •Оператор присваивания
- •Странные операторы присваивания
- •Функции ввода-вывода
- •Функции ввода исходных данных с клавиатуры
- •Потоковый ввод данных числового типа
- •Функция форматного ввода
- •Операторы вывода данных на экран Потоковый вывод
- •Форматный вывод
- •Контрольные задания
- •2.7. Разветвляющиеся вычислительные процессы
- •If (логическое выражение) p1; else p2;
- •Логические выражения
- •Порядок выполнения операций в логических выражениях
- •Условные операторы
- •Короткий условный оператор
- •Полный условный оператор
- •If (логическое выражение) { p1;} else {p2;}
- •Вложенные структуры условных операторов
- •Оператор выбора
- •Контрольные задания
- •2.8. Циклические вычислительные процессы
- •Операторы цикла с условием
- •Оператор цикла с параметром
- •2.9. Базовые алгоритмы
- •Задача 1. Алгоритм организации счетчика
- •Задача 2. Алгоритм накопления суммы
- •Задача 3. Алгоритм накопления произведения
- •Задача 4. Алгоритм поиска минимального члена последовательности
- •Задача 5. Табулирование функции (или кратные циклы)
- •Задача 6. Вычисление сумм элементов последовательностей
- •2.10. Указатели и массивы
- •2.10.1. Указатели
- •2.10.2. Понятие массива
- •Одномерные массивы
- •Описание одномерного массива
- •Индексированные переменные
- •Ввод-вывод одномерных массивов
- •Обработка одномерных массивов
- •Задача 1. Организация счетчика
- •Задача 2. Накопление суммы и произведения
- •Задача 3. Поиск минимального и максимального элементов массива
- •Двухмерные массивы
- •Описание двухмерного массива
- •Ввод-вывод двухмерного массива
- •Обработка матриц
- •2.11. Подпрограммы Структура сложной программы
- •Функции
- •Общий вид описания функции
- •Int I,j; //локальные переменные
- •Обращение к функции
- •Пример программы с функцией
- •Механизмы замены параметров
- •Параметры-массивы в функциях
- •Возвращение результатов
- •Примеры программирования задач с использованием подпрограмм Задача 1
- •Рекурсия
- •Технология сборки библиотеки
- •2.12. Текстовые данные
- •Символьный тип данных
- •Ввод-вывод символьных данных
- •Обработка символьных данных
- •Ввод-вывод строковых данных
- •Обработка строковых данных
- •Стандартные функции обработки строк
- •Сравнение строк:
- •Сцепление строк
- •Определение длины строки
- •Копирование строк
- •Поиск символа в стоке
- •Пример программы для задачи с текстовыми данными
- •Контрольные задания
- •2.13. Динамическое выделение памяти
- •Использование оператора new
- •Освобождение памяти
- •Структуры данных Понятие структуры
- •Обработка структур
- •Пример задачи с использованием структурированных данных
- •2.15. Файлы данных
- •2.15.1. Работа с файлами в стиле с
- •Объявление файловой переменной
- •Открытие файла
- •Закрытие файла
- •// Обработка открытого файла
- •Обработка открытого файла
- •Функции ввода/вывода
- •Работа с текстовыми файлами
- •Обработка бинарных файлов
- •Контрольные задания
- •Заключение
- •Оглавление
- •Литература
- •Приложение
Возвращение результатов
Результат работы функции возвращается в точку вызова с помощью оператора
return [выражение];
Таким образом, функция может вернуть только одно скалярное значение. Если функция должна вернуть несколько результатов, то этот возврат реализуется с помощью указателей, т.е. параметров, передаваемых по адресу.
Теория создания функций, рассмотренная в данном параграфе, является базовой и будет достаточной для начинающих программистов. Для более глубоко изучения данного вопроса следует обратиться, например [4]. Но, даже изучив теорию в таком объеме, у нас есть возможность научить вас собирать собственные библиотечные файлы.
Примеры программирования задач с использованием подпрограмм Задача 1
Даны два вектора: = {хi}; i =и={yi};i =.
Вычислить значение: D = , где ;;
тх, ту - максимальные компоненты векторов и соответственно;
sx, sy - средние значения компонент векторов и соответственно.
Решение:
#include "stdafx.h"
#include <math.h>
float Mod_Otk(float *a, int n) /* типизированная функция для нахождения максимального компонента и среднего значения в любом массиве */
{
float maxi, sa, Da; //описание локальных переменных
int i;
maxi =-10000;
sa=0;
for (i =0;i<n;i++)
{
if (a[i]>maxi) maxi= a[i];
sa += a[i];
}
sa = sa/n;
Da= fabs(maxi - sa);
return Da;
}
void main()
{ float X[10],Y[10];
int i;
float Dx, Dy, D;
printf("Bведитe массив X:\n");
for (i =0;i<8;i++)
scanf("%f",&X[i]);
printf("Bведитe массив Y:\n");
for (i =0;i<10;i++)
scanf("%f",&Y[i]);
Dx = Mod_Otk(X, 8);//вызов функции Mod_Otk для массива X
Dy = Mod_Otk(Y,10);//вызов функции Mod_Otk для массива Y
D = Dx/Dy;
printf("D=%f\n",D);
}
Задача 2
Даны две матрицы: А = {a i j }5x6 и В = {b i j}4x7.
Вычислить разность: С = КА - KB, где КА и KB - количество положительных элементов в матрицах А и В соответственно.
#include "stdafx.h"
int CP(float D[7][7], int m, int n) /*типизированная функция для подсчета количества положительных элементов в любой матрице */
{ int i, j, KD;
KD=0;// инициализация счетчика
for (i=0;i<m;i++)
for (j=0;j<n;j++)
if (D[i][j]>0) KD ++; /*добавление в счетчик единицы, если элемент матрицы окажется >0 */
return KD; // возвращение результата в точку вызова
}
int main()
{
float A[7][7], B[7][7];
int i,j, C;
printf("Введите матрицу А\n");
for (i=0;i<5;i++)
for (j=0;j<6;j++)
scanf("%f",&A[i][j]);
printf("Введите матрицу B\n");
for (i=0;i<4;i++)
for (j=0;j<7;j++)
scanf("%f",&B[i][j]);
C= CP(A, 5,6)- CP(B, 4, 7); //вызовы функции СР
printf("C=%d\n", C);
return 0;
}
Задача 3
На плоскости декартовыми координатами заданы 10 точек:
{x1,y1},{x2,y2}, ...,{х10,у10}.
Вывести полярные координаты точки, имеющей наибольший полярный радиус. Вычисление полярных координат одной точки оформить подпрограммой. Расчетные формулы для вычисления полярных координат следующие:
, где а и b -декартовы координаты точки.
Решение:
#include "stdafx.h"
#include<math.h>
void PK(float a, float b, float *ro, float *fi)
/* безтиповая функция для расчета полярных координат точки */
{
*ro = sqrt(a*a + b*b);
*fi = atan(b/a);
}
int main()
{
float X[10], Y[10]; // масcивы для декартовых координат точек
float R[10], F[10]; // масcивы для полярных координат точек
int i, N;
float maxR;
printf("Введите абсциссы 10 точек\n");
for (i=0;i<10;i++) scanf("%f",&X[i]);
printf(" Введите ординаты 10 точек\n");
for (i=0;i<10;i++) scanf("%f",&Y[i]);
maxR = 0;
for (i=0;i<10;i++)
{
PK(X[i],Y[i],&R[i],&F[i]);
if (R[i]>maxR) // поиск максимального радиуса
{
maxR =R[i];
N=i; /*запоминаем номер точки, радиус которой больше, чем у предыдущих */
}
}
printf("romax=%f fimax=%f\n", R[N],F[N]);/* вывод полярных координат точки с номером N */
return 0;
}
Задача 4
Для заданных квадратных матриц: A = {a i j}3x3 и В = {bi j}4х4 вычислить симметричные им матрицы по правилу:
, x- матрица , симметричная матрице y.
Решение:
#include "stdafx.h"
void SM(float Y[4][4], int n, float X[4][4])/*безтиповая функция вычисления симметричной матрицы X из исходной матрицы Y */
{
int i,j;
for (i=0;i<n;i++)
for (j=i;j<n;j++)
{
X[i][j]=(Y[i][j] + Y[j][i])/2;
X[j][i] =X[i][j];
}
}
void VIVOD(float Y[4][4], int n)//функция вывода матрицы
{for (i=0;i<n;i++)
{for (j=0;j<n;j++) printf("%8.2f",Y[i][j]);
printf("\n");
}
}
void main()
{
float A[4][4], B[4][4], C[4][4], D[4][4];
int i, j;
printf("Введите матрицу А\n");
for (i=0;i<3;i++)
for (j=0;j<3;j++) scanf("%f",&A[i][j]);
printf("Введите матрицу B\n");
for (i=0;i<4;i++)
for (j=0;j<4;j++) scanf("%f",&B[i][j]);
SM(A, 3,C); // обращение к функции SM для матрицы A
SM(B, 4, D); //обращение к функции SM для матрицы B
printf("Симметричная матрица С\n");
VIVOD(C,3);
printf("Симметричная матрица D\n");
VIVOD(D,4);
}
Перегрузка функций в С++
Перегруженная функция – это функция, которая позволяет при обращении к себе варьировать типы передаваемых параметров. Цель перегрузки состоит в том, чтобы функция с одним и тем же именем возвращала разного типа значение при обращении к ней с различными типами фактических параметров. Рассмотрим этот механизм на примере некоторой абстрактной функции с именем SUM. Допустим, мы имеем три варианта функции SUM.
float SUM (float a, float b);
//принимает два вещественных аргумента и возвращает результат ввиде вещественного числа
double SUM (double a, double b);
//принимает два аргумента вещественного длинного типа и возвращает результат ввиде вещественного длинного числа
complex SUM (complex a, complex b);
//принимает два аргумента комплексного типа и возвращает результат ввиде комплексного числа
Компилятор определит, какую именно функцию с именем SUM надо вызвать по типу передаваемых ей параметров.
Наполним функцию SUM банальным алгоритмом вычисления суммы двух чисел.
#include "stdafx.h"
#define complex struct compl
complex
{double x,y;};
complex SUM (complex a, complex b)
{complex c;
c.x=a.x+b.x;
c.y=a.y+b.y;
return c;
}
float SUM (float a, float b)
{float c;
c=a+b;
return c;
}
double SUM (double a, double b)
{ double c;
c=a+b;
return c;
}
int _tmain(int argc, _TCHAR* argv[])
{complex z,m,n;
float a=4.5,b=6.5;
z.x=5; z.y=6;
m.x=7;m.y=8;
n= SUM (z,m); //вызов функции SUM для комплексных параметров
printf("%lf+i%lf\n",n.x,n.y);
float d= SUM (a,b); //вызов функции SUM для вещественных параметров
printf("d=%f\n",d);
float d2= SUM (10,35); //неоднозначный вызов функции SUM
printf("d2=%f\n",d2);
return 0;
}
Использование нескольких функций с одним и тем же именем, но с различными типами параметров, называется перегрузкой функций.
По типам фактических параметров компилятор определяет, какую именно функцию требуется вызвать. Этот процесс называется разрешением перегрузки (перевод английского слова resolution в смысле «уточнение»). Тип возвращаемого функцией значения в разрешении не участвует. Механизм разрешения основан на достаточно сложном наборе правил, смысл которых сводится к тому, чтобы использовать функцию с наиболее подходящими аргументами или выдать сообщение, если такой не найдется. Если точного соответствия не найдено, выполняется преобразование типов параметров по общим правилам, например char в int; int во float, float в double; и т.п. Если соответствие может быть получено более чем одним способом, вызов считается неоднозначным и выдается сообщение об ошибке. В нашем примере это продемонстрировано вызовом третьим, когда в функцию SUM передаются в качестве параметров два целых числа 10 и 35. Эти параметры могут быть преобразованы как в тип float, так и в тип double, что и вызовет возникновение ошибочной неоднозначности.
При создании перегруженных функций необходимо придерживаться следующих правила:
• Перегруженные функции должны находиться в одной области видимости,
иначе произойдет сокрытие аналогично тому, как это происходит с одинаковыми именами переменных во вложенных блоках.
• Перегруженные функции могут иметь параметры по умолчанию, при этом
значения одного и того же параметра в разных функциях должны совпадать.
В различных вариантах перегруженных функций может быть различное количество параметров по умолчанию.
• Функции не могут быть перегружены, если описание их параметров отличается только модификатором const (например, int и const int ), или использованием ссылки (например, int и int&).
Более подробную информацию о перегруженных функциях см. в [2].