Урок 2. C++ многофайловая компоновка, функции

Дата изменения: 23 сентября 2022
На занятии объясняется тема «язык С++: функции». Также рассмотрены типы данных c++ (double, int и другие)

Теория/h2>

Стандартные функции

Математические функции объявлены с включением библиотеки <cmath>:

#include <cmath>
abs(x);  
floor(x);  
sin(x);  
pow(x, y);  
sqrt(x);

Пользовательские функции

пример 1:

//...
int abs(int x) {
	return x > 0 ? x : -x;  // выход из функции
}
int main() {
	cout << abs(-35); // 35
	system("pause");
	return 0;
}

Функция abs возвращает целочисленное значение по модулю и имеет единственный целочисленный параметр x.

пример 2:

//...
void print(int i) {
	cout << "значение = " << i;
}
int main() {
	print(40);
	system("pause");
	return 0;
}

Функция print не возвращает никакого значения и имеет единственный целочисленный параметр i. Мы можем назвать это процедурой (потому что она не возвращает значение).

Инкапсуляция

В C++ данные и функции разделены на две отдельные группы с уровнем доступа: public и private.
Уровень определяет доступ, который «клиентский код» имеет к данным или функциям:

  • Доступ к объектам с уровнем доступа Public можно получить из клиентского кода.
  • Доступ к объектам с уровнем доступа Private получить из клиентского кода невозможно (доступ только из самих функций).

В C++ объявление функций (в файле .h) отделены от ее реализации (в файл .cpp).

Многофайловая компоновка

Для создания приложения обычно требуется создать 3 файла: файл заголовка (.h), файл реализации (.cpp) и основной файл (.cpp).

  • Заголовочный файл (.h) определяет интерфейс к функциям, то есть объявление(я) функции(й).
  • Файл реализации .cpp содержит всю логику функций или методов (то есть тело функций). Кроме того, здесь должен быть включен файл заголовка .h.
  • Основной файл .cpp содержит функцию main — так называемая «точка входа», с которой осуществляется запуск программ на C++, и сюда также необходимо включить заголовочный файл .h.

Рассмотрим на примере (три файла одного и того же приложения):

Пример заголовочного файла (tasks.h):

#ifndef TASKS_H
#define TASKS_H
//вычисляет периметр треугольника
double perimeter(double, double, double);
#endif TASKS_H

Пример файла реализации (.cpp):

#include "tasks.h"
//вычисляет периметр треугольника
double perimeter(double a, double b, double c)
{
	//операторы
}

Пример главного файла (.cpp):

#include <iostream>
#include "tasks.h"
using namespace std;
void main()
{
	//запросить у пользователя ввод данных
	//вызов функции
	//вывод результатов
	system("pause");
}

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

Лабораторные работы

Лабораторная работа 1:

Выполнить: Создайте приложение для нахождения объема и площади поверхности куба. Дана длина стороны куба (она вводится).

Примечание: Необходимо представить три решения: 1) Без пользовательских функции и без многофайлового приложения, 2) С пользовательскими функциями, 3) Создание многофайлового приложения.

Примерный вывод:

Введите длину стороны куба: 3.48
Объем: 42.1442
Площадь поверхности: 72.6624

[Имя проекта: Lesson_2Lab1, имена файлов HeaderL2Lab1.h, ImpL2Lab1.cpp, MainL2Lab1.cpp]

✍ Алгоритм:

  1. Откройте Microsoft Visual Studio. Выберите в меню Файл/File -> Новый проект/New project. Выберите язык C++ и консольное приложение.
  2. Назовите проект Lesson_2Lab1.
  3. В окне Обозреватель решений/Solution Explorer найдите папку Файлы источники/Source files и в контекстном меню папки выбрать Добавить/Add -> Новый файл/New Item. Необходимо создать два .cpp файла и назвать их: ImpL2Lab1.cpp – файл реализации и MainL2Lab1.cpp – файл с функцией main.
  4. Затем найдите папку Файлы заголовков/Header files и в контекстном меню папки выберите Добавить/Add -> Новый файл/New Item. Добавьте заголовочный файл с расширением .h и назовите его HeaderL2Lab1.h.
  5.   
    1) Без пользовательских функций и без многофайлового приложения:

  6. Сначала выполним задание без пользовательских функций. То есть, необходимо задать значение для стороны куба и посчитать объем и площадь поверхности куба.
  7. Объявите переменную типа double и назовите ее length. Запросите ввести значение для нее. Не забудьте подключить библиотеку iostream для осуществления ввода и вывода в консоль:
  8. #include <iostream>
    int main() {
    double length;
    	std::cout << "Введите длину стороны куба: ";
    	std::cin >> length;
    	// …
    }
    
  9. Для того, чтобы окно консоли не закрылось сразу после вывода, необходимо добавить паузу (pause). Функция main должна возвратить 0:
  10. //…
       system("pause");
       return 0;
    }
    
  11. Объявите переменные для объема и площади. Выполните вычисление по формулам и присвойте результаты переменным:
  12. 	double volume = length * length * length;
    	double surfaceArea = 6 * length * length;
    
  13. Выведите результаты в консоль:
  14.    std::cout << "Объем: " << volume << std::endl;
       std::cout << "Площадь поверхности: " << surfaceArea << std::endl;
    
  15. Запустите приложение и проверьте вывод. Покажите преподавателю
  16.  
    2) Использование пользовательских функций:

  17. Теперь будем создавать пользовательские функции для расчета объем и площади.
  18. Найдите строки кода с объявлением переменных и расчетами. Закомментируйте их:
  19. //double volume = length * length * length;
    //double surfaceArea = 6 * length * length;
    
  20. Создадим метод (функцию) с названием getVolume для вычисления объема. Метод должен возвращать значение типа double (вещественный тип), так как сторона куба тоже вещественного типа. Объявление метода необходимо расположить до функции main:
  21. double getVolume(double length);
    double getVolume(double length)
    {
    	return length * length * length;
    }
    int main() {
        //…
    
  22. Добавьте объявление переменной length в функцию main:
  23. int main() {
    	double length;
    
  24. Создайте метод getSurfaceArea для вычисления площади поверхности куба. Метод также должен возвращать значение типа double. Расположите код перед функцией main:
  25. double getSurfaceArea(double length);
    double getSurfaceArea(double length) {
    	return 6 * length * length;
    }
    
  26. Компилятор не извлечет функции, пока мы их не вызовем. Таким образом, необходимо вызвать функции и результат, который они вернут сохранить в переменные. Расположите код в функцию main:
  27. double volume = getVolume(length);
    double surfaceArea = getSurfaceArea(length);
    
  28. Запустите приложение и проверьте вывод. Результаты должны быть такими же, как и при первом выполнении задания. Покажите результаты преподавателю.
  29. 3) Создание многофайлового приложения

  30. В окне Обозреватель решений/Solution Explorer выберите заголовочный файл (HeaderL2Lab1.h). В код файла добавьте объявление методов, предварительно вырезав их из главного файла (в главном файле их не должно остаться):
  31. #pragma once
    // вычисление объема куба
    double getVolume(double length);
    // вычисление площади поверхности 
    double getSurfaceArea(double length);
    
    — Обратите внимание на то, что в заголовочном файле .h мы не добавляем код реализации функции, а только ее объявление (сигнатуру функции). Для тог, чтобы увидеть код работы функции (ее реализации) необходимо перейти в .cpp файл.
    — Директива pragma once дает команду компилятору выполнять код только один раз. Даже если много файлов (пользователей) одновременно будут использовать данный класс, объявление методов должно быть единственным.
    — Перед каждой функцией необходимо размещать комментарии с пояснением того, для чего служит эта функция.
  32. В окне Обозреватель решений / Solution Explorer выберите файл реализации (ImpL2Lab1.cpp). В данном файле необходимо разместить тело функций — их реализацию (вырежьте эти фрагменты кода из главного файла и добавьте сюда). И не забудьте подключить заголовочный файл в самой верхней строке:
  33. #include "HeaderL2Lab1.h"
    double getVolume(double length)
    {
    	return length * length * length;
    }
    double getSurfaceArea(double length) {
    	return 6 * length * length;
    }
    
    — We call this file the implementation file and it’s the code that contains all of the logic to implement our methods.
    — We have a pound (#) include that includes a reference to our header.
    — We have the implementation of our two functions that were defined in our .h file.
  34. Now, we can go ahead and clear up the parts of a code we don’t need anymore within the main function. So, this is what you have in your MainL2Lab1.cpp:
  35. #include <iostream>
    #include " HeaderL2Lab1.h"
    int main(){
    	double length;
    	std::cout << "please enter the cube side length: ";
    	std::cin >> length;
            //double volume = length * length * length;
    	//double surfaceArea = 6 * length * length;
    	double volume = getVolume(length);
    	double surfaceArea = getSurfaceArea(length);
    	std::cout << "Volume: " << volume << std::endl;
    	std::cout << "Surface area: " << surfaceArea << std::endl;
    	system("pause");
    	return 0;
    }
    
  36. Run the application and check the output. The results must be as they were.
  37. Three files must be uploaded to the moodle system: HeaderL2Lab1.h, ImpL2Lab1.cpp, MainL2Lab1.cpp.

Notes on all tasks

  • To make the following tasks you’ll need 3 files: tasks.h, tasks.cpp, main.cpp. Download them and place them into the Lesson_2Lab1 folder.
  • When all the tasks you intended to do have been completed, upload those three files to the moodle.
  • [Solution and Project name: Lesson_2Lab1, files’ names tasks.h, tasks.cpp, main.cpp]

    Task 0:

    To do: Create a Sum() method that takes two integer arguments and sums them. The method returns the result of integer type.

    Note: You need to create the method declaration in the tasks.h file by yourself, and also the method implementation must be written in the tasks.cpp file. Call the function within the main.cpp. Don’t forget to use the comments to explain the purpose of the method.

    Expected output:

    Please, enter two numbers
    20 40 
    The sum of 20 and 40 is: 60
    

    [Solution and Project name: Lesson_2Lab1, files’ names tasks.h, tasks.cpp, main.cpp]

    Task 1:

    To do: Ask user to enter the lengths of the three sides of the triangle. Create a method named perimeter that calculates the perimeter of a triangle from the lengths of its three sides.

    Note: Three files must be used to complete the task. Check the code of the files and fill in the places marked as // TODO related to this task.

    Expected output:

    please enter three numbers for the triangle three sides: 3.0  4.1  5.0
    the perimeter is: 12.1
    

    [Solution and Project name: Lesson_2Lab1, files’ names tasks.h, tasks.cpp, main.cpp]

    Task 2:

    To do: Ask user to enter the lengths of the three sides of the triangle. Create a method named areaFromSides that calculates the area of a triangle by the lengths of its three sides using Heron’s formula:

    where p stands for semi-perimeter.

    Note 1: Three files must be used to complete the task. Check the code of the files and fill in the places marked as // TODO related to this task.

    Note 2: To calculate a square root the math libtary is needed to be included and sqrt() function:

    #include <cmath>

    Expected output:

    please enter three numbers for the triangle three sides: 
    2 4 5
    the area is: 
    6
    

    [Solution and Project name: Lesson_2Lab1, files’ names tasks.h, tasks.cpp, main.cpp]

    Task 3:

    To do: Ask user to enter the coordinates of triangle vertices ((x1,y1); (x2,y2); (x3,y3)). Create a method named areaFromPos that calculates the area of a triangle using the coordinates of its vertices.

    Note 1: Three files must be used to complete the task. Check the code of the files and fill in the places marked as // TODO related to this task.

    Note 2: The math libtary is needed:

    #include <cmath>

    Expected output:

    please enter six numbers for the coordinates of the triangle vertices:
    4 6 2 9 1 7
    the area is: 3
    

    [Solution and Project name: Lesson_2Lab1, files’ names tasks.h, tasks.cpp, main.cpp]

    Task 4:

    To do: Ask user to enter the coordinates of two points. Create a function named dist that calculates the distance between two points on the plane, using their coordinates. [sqrt].

    Note: Formula to calculate the distance between two points:

    Note: To check to see if your result is right you can calculate the distance in the wolframalpha service. For example, to find the distance between points (1, -2) and (4, 2), use command distance ({1, -2}, {4, 2}).

    Note: Three files must be used to complete the task. Check the code of the files and fill in the places marked as // TODO related to this task.

    Expected output:

    Please enter the coordinates of two points (four integers: x1, y1, x2, y2):
    1 -2  4  2
    The distance is: 5
    

    [Solution and Project name: Lesson_2Lab1, files’ names tasks.h, tasks.cpp, main.cpp]

    Task 5:

    To do: Create GetPow() method that takes two integer arguments, they are base number and power number. The method returns the result of taking a base number to power number.

    Note: Three files must be used to complete the task. Check the code of the files and fill in the places marked as // TODO related to this task.

    Expected output:

    Please enter two numbers – a base number and a power number:
    2  4 
    Base number 2 raised to the power number 4 = 16
    

    [Solution and Project name: Lesson_2Lab1, files’ names tasks.h, tasks.cpp, main.cpp]

    Task 6:

    To do: Define Mean(X, Y) function that calculates the arithmetic mean and geometric mean ((√X*Y)) of two positive decimal numbers X and Y. X and Y are input parameters. The function must not return any values, it has to print the results out to the console window.

    Note: You can use the standard function to calculate the square root of a number (sqrt()). But you need to include a math library:

    #include <cmath>

    Note: To print out the floating point number with 3 digits after the point, you should use the following function:

    printf("%.3f ",result)

    Expected output:

    please enter two numbers: 
    
    <<15.0  <<4.0
    arithmetic mean: 9.500
    geometric mean: 7.746
    

    [Solution and Project name: Lesson_2Task6, files’ names task6.h, task6.cpp, main6.cpp]

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    *
    *

    Вставить формулу как
    Блок
    Строка
    Дополнительные настройки
    Цвет формулы
    Цвет текста
    #333333
    Используйте LaTeX для набора формулы
    Предпросмотр
    \({}\)
    Формула не набрана
    Вставить