Технический форум
Вернуться   Технический форум > Программирование > Форум программистов > C/C++/С#


Результаты опроса: Нужна ли публикация уроков по C++ ?
Да 29 93.55%
Нет 2 6.45%
Голосовавшие: 31. Вы ещё не голосовали в этом опросе

Ответ
 
Опции темы Опции просмотра
Старый 17.04.2013, 01:56   #11 (permalink)
Gruvi
VIP user
 
Аватар для Gruvi
 
Регистрация: 10.03.2011
Сообщений: 765
Записей в дневнике: 1
Сказал(а) спасибо: 10
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 3453
По умолчанию

Параметры командной строки в C++ — урок 9

При запуске программы из командной строки, ей можно передавать дополнительные параметры в текстовом виде. Например, следующая команда

Цитата:
ping -t 5 google.com
Будет отправлять пакеты на адрес google.com с интервалом в 5 секунд. Здесь мы передали программе ping два параметра — это задержка между запросами и адрес хоста для обмена пакетами.

Эти параметры описываются, как аргументы функции main(). Первый аргумент — это количество параметров, которые были переданы программе. В качестве первого аргумента всегда передается название самого файла программы. Второй аргумент — это массив, хранящий все остальные параметры.
Пример 1.1
Цитата:
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
for (int i = 0; i < argc; i++) {
// Выводим список аргументов в цикле
cout << "Argument " << i << " : " << argv[i] << endl;
}
return 0;
}
Откройте командную строку и запустите оттуда скомпилированную программу.
Для получения числовых данных из входных параметров, можно использовать функции atoi и atof.
Gruvi вне форума   Ответить с цитированием

Старый 17.04.2013, 01:56
Helpmaster
Member
 
Аватар для Helpmaster
 
Регистрация: 08.03.2016
Сообщений: 0

По этим ссылкам содержаться темы, которые по содержанию схожи с вашей

Простые уроки по HTML
Жучок для начинающих
Уроки CSS
Аэрография для начинающих
Набор радиокомпонентов для начинающих

Старый 23.04.2013, 00:18   #12 (permalink)
Gruvi
VIP user
 
Аватар для Gruvi
 
Регистрация: 10.03.2011
Сообщений: 765
Записей в дневнике: 1
Сказал(а) спасибо: 10
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 3453
По умолчанию

Классы в C++ — урок 10

Весь реальный мир состоит из объектов. Города состоят из районов, в каждом районе есть свои названия улиц, на каждой улице находятся жилые дома, которые также состоят из объектов.

Практически любой материальный предмет можно представить в виде совокупности объектов, из которых он состоит. Допустим, что нам нужно написать программу для учета успеваемости студентов. Можно представить группу студентов, как класс языка C++. Назовем его Students.

Основные понятия
Модификаторы доступа public и private
Программа учета успеваемости студентов
Отделение данных от логики
Создание объекта через указатель
Конструктор и деструктор класса

Цитата:
class Students {
// Имя студента
std::string name;
// Фамилия
std::string last_name;
// Пять промежуточных оценок студента
int scores[5];
// Итоговая оценка за семестр
float average_ball;
};
Основные понятия

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

У каждого студента есть имя — name и фамилия last_name . Также, у него есть промежуточные оценки за весь семестр. Эти оценки мы будем записывать в целочисленный массив из пяти элементов. После того, как все пять оценок будут проставлены, определим средний балл успеваемости студента за весь семестр — свойство average_ball.

Методы — это функции, которые могут выполнять какие-либо действия над данными (свойствами) класса. Добавим в наш класс функцию calculate_average_ball(), которая будет определять средний балл успеваемости ученика.

Методы класса — это его функции.
Свойства класса — его переменные.
Цитата:
class Students {
public:
// Функция, считающая средний балл
void calculate_average_ball()
{
int sum = 0; // Сумма всех оценок
for (int i = 0; i < 5; ++i) {
sum += scores[i];
}
// считаем среднее арифметическое
average_ball = sum / 5.0;
}

// Имя студента
std::string name;
// Фамилия
std::string last_name;
// Пять промежуточных оценок студента
int scores[5];

private:
// Итоговая оценка за семестр
float average_ball;
};
Функция calculate_average_ball() просто делит сумму всех промежуточных оценок на их количество.
Модификаторы доступа public и private

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

Закрытые данные класса размещаются после модификатора доступа private:. Если отсутствует модификатор public, то все функции и переменные, по умолчанию являются закрытыми (как в первом примере).

Обычно, приватными делают все свойства класса, а публичными — его методы. Все действия с закрытыми свойствами класса реализуются через его методы. Рассмотрим следующий код.

Цитата:
class Students {
public:
// Установка среднего балла
void set_average_ball(float ball)
{
average_ball = ball;
}
// Получение среднего балла
float get_average_ball()
{
return average_ball;
}
std::string name;
std::string last_name;
int scores[5];

private:
float average_ball;
};
Мы не можем напрямую обращаться к закрытым данными класса. Работать с этими данными можно только посредством методов этого класса. В примере выше, мы используем функцию get_average_ball() для получения средней оценки студента, и set_average_ball() для выставления этой оценки.

Функция set_average_ball() принимает средний балл в качестве параметра и присваивает его значение закрытой переменной average_ball. Функция get_average_ball() просто возвращает значение этой переменной.
Программа учета успеваемости студентов

Создадим программу, которая будет заниматься учетом успеваемости студентов в группе. Создайте заголовочный файл students.h, в котором будет находиться класс Students.

Цитата:
/* students.h */
#include <string>

class Students {
public:
// Установка имени студента
void set_name(std::string student_name)
{
name = student_name;
}
// Получение имени студента
std::string get_name()
{
return name;
}
// Установка фамилии студента
void set_last_name(std::string student_last_name)
{
last_name = student_last_name;
}
// Получение фамилии студента
std::string get_last_name()
{
return last_name;
}
// Установка промежуточных оценок
void set_scores(int student_scores[])
{
for (int i = 0; i < 5; ++i) {
scores[i] = student_scores[i];
}
}
// Установка среднего балла
void set_average_ball(float ball)
{
average_ball = ball;
}
// Получение среднего балла
float get_average_ball()
{
return average_ball;
}

private:
// Промежуточные оценки
int scores[5];
// Средний балл
float average_ball;
// Имя
std::string name;
// Фамилия
std::string last_name;
};
Мы добавили в наш класс новые методы, а также сделали приватными все его свойства. Функция set_name() сохраняет имя студента в переменной name, а get_name() возвращает значение этой переменной. Принцип работы функций set_last_name() и get_last_name() аналогичен.

Функция set_scores() принимает массив с промежуточными оценками и сохраняет их в приватную переменную int scores[5].

Теперь создайте файл main.cpp со следующим содержимым.
Цитата:
/* main.cpp */
#include <iostream>
#include "students.h"

int main()
{
// Создание объекта класса Student
Students student;

std::string name;
std::string last_name;

// Ввод имени с клавиатуры
std::cout << "Name: ";
getline(std::cin, name);

// Ввод фамилии
std::cout << "Last name: ";
getline(std::cin, last_name);

// Сохранение имени и фамилии в объект класса Students
student.set_name(name);
student.set_last_name(last_name);

// Оценки
int scores[5];
// Сумма всех оценок
int sum = 0;

// Ввод промежуточных оценок
for (int i = 0; i < 5; ++i) {
std::cout << "Score " << i+1 << ": ";
std::cin >> scores[i];
// суммирование
sum += scores[i];
}

// Сохраняем промежуточные оценки в объект класса Student
student.set_scores(scores);
// Считаем средний балл
float average_ball = sum / 5.0;
// Сохраняем средний балл в объект класса Students
student.set_average_ball(average_ball);
// Выводим данные по студенту
std::cout << "Average ball for " << student.get_name() << " "
<< student.get_last_name() << " is "
<< student.get_average_ball() << std::endl;

return 0;
}
В самом начале программы создается объект класса Students. Дело в том, что сам класс является только описанием его объекта. Класс Students является описанием любого из студентов, у которого есть имя, фамилия и возможность получения оценок.

Объект класса Students характеризует конкретного студента. Если мы захотим выставить оценки всем ученикам в группе, то будем создавать новый объект для каждого из них. Использование классов очень хорошо подходит для описания объектов реального мира.

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

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

Скомпилируйте и запустите программу.

Отделение данных от логики

Вынесем реализацию всех методов класса в отдельный файл students.cpp.
Цитата:
/* students.cpp */
#include <string>
#include "students.h"

// Установка имени студента
void Students::set_name(std::string student_name)
{
Students::name = student_name;
}

// Получение имени студента
std::string Students::get_name()
{
return Students::name;
}

// Установка фамилии студента
void Students::set_last_name(std::string student_last_name)
{
Students::last_name = student_last_name;
}

// Получение фамилии студента
std::string Students::get_last_name()
{
return Students::last_name;
}

// Установка промежуточных оценок
void Students::set_scores(int scores[])
{
for (int i = 0; i < 5; ++i) {
Students::scores[i] = scores[i];
}
}

// Установка среднего балла
void Students::set_average_ball(float ball)
{
Students::average_ball = ball;
}

// Получение среднего балла
float Students::get_average_ball()
{
return Students::average_ball;
}

А в заголовочном файле students.h оставим только прототипы этих методов.

/* students.h */
#pragma once /* Защита от двойного подключения заголовочного файла */
#include <string>

class Students {
public:
// Установка имени студента
void set_name(std::string);
// Получение имени студента
std::string get_name();
// Установка фамилии студента
void set_last_name(std::string);
// Получение фамилии студента
std::string get_last_name();
// Установка промежуточных оценок
void set_scores(int []);
// Установка среднего балла
void set_average_ball(float);
// Получение среднего балла
float get_average_ball();

private:
// Промежуточные оценки
int scores[5];
// Средний балл
float average_ball;
// Имя
std::string name;
// Фамилия
std::string last_name;
};
Такой подход называется абстракцией данных — одного из фундаментальных принципов объектно-ориентированного программирования. К примеру, если кто-то другой захочет использовать наш класс в своем коде, ему не обязательно знать, как именно высчитывается средний балл. Он просто будет использовать функцию calculate_average_ball() из второго примера, не вникая в алгоритм ее работы.

Над крупными проектами обычно работает несколько программистов. Каждый из них занимается написанием определенной части продукта. В таких масштабах кода, одному человеку практически нереально запомнить, как работает каждая из внутренних функций проекта. В нашей программе, мы используем оператор потокового вывода cout, не задумываясь о том, как он реализован на низком уровне. Кроме того, отделение данных от логики является хорошим тоном программирования.

В начале обучения мы говорили о пространствах имен (namespaces). Каждый класс в C++ использует свое пространство имен. Это сделано для того, чтобы избежать конфликтов при именовании переменных и функций. В файле students.cpp мы используем оператор принадлежности :: перед именем каждой функции. Это делается для того, чтобы указать компилятору, что эти функции принадлежат классу Students.
Создание объекта через указатель

При создании объекта, лучше не копировать память для него, а выделять ее в в куче с помощью указателя. И освобождать ее после того, как мы закончили работу с объектом. Реализуем это в нашей программе, немного изменив содержимое файла main.cpp.
Цитата:
/* main.cpp */
#include <iostream>
#include "students.h"

int main()
{
// Выделение памяти для объекта Students
Students *student = new Students;

std::string name;
std::string last_name;

// Ввод имени с клавиатуры
std::cout << "Name: ";
getline(std::cin, name);

// Ввод фамилии
std::cout << "Last name: ";
getline(std::cin, last_name);

// Сохранение имени и фамилии в объект класса Students
student->set_name(name);
student->set_last_name(last_name);

// Оценки
int scores[5];
// Сумма всех оценок
int sum = 0;

// Ввод промежуточных оценок
for (int i = 0; i < 5; ++i) {
std::cout << "Score " << i+1 << ": ";
std::cin >> scores[i];
// суммирование
sum += scores[i];
}
// Сохраняем промежуточные оценки в объект класса Student
student->set_scores(scores);

// Считаем средний балл
float average_ball = sum / 5.0;
// Сохраняем средний балл в объект класса Students
student->set_average_ball(average_ball);
// Выводим данные по студенту
std::cout << "Average ball for " << student->get_name() << " "
<< student->get_last_name() << " is "
<< student->get_average_ball() << std::endl;
// Удаление объекта student из памяти
delete student;
return 0;
}
При создании статического объекта, для доступа к его методам и свойствам, используют операция прямого обращения — «.» (символ точки). Если же память для объекта выделяется посредством указателя, то для доступа к его методам и свойствам используется оператор косвенного обращения — «->».
Конструктор и деструктор класса

Конструктор класса — это специальная функция, которая автоматически вызывается сразу после создания объекта этого класса. Он не имеет типа возвращаемого значения и должен называться также, как класс, в котором он находится. По умолчанию, заполним двойками массив с промежуточными оценками студента.
Цитата:
class Students {
public:
// Конструктор класса Students
Students(int default_score)
{
for (int i = 0; i < 5; ++i) {
scores[i] = default_score;
}
}

private:
int scores[5];
};

int main()
{
// Передаем двойку в конструктор
Students *student = new Students(2);
return 0;
}
Мы можем исправить двойки, если ученик будет хорошо себя вести, и вовремя сдавать домашние задания. А на «нет» и суда нет :-)

Деструктор класса вызывается при уничтожении объекта. Имя деструктора аналогично имени конструктора, только в начале ставится знак тильды ~. Деструктор не имеет входных параметров.
Цитата:
#include <iostream>

class Students {
public:
// Деструктор
~Students()
{
std::cout << "Memory has been cleaned. Good bye." << std::endl;
}
};

int main()
{
Students *student = new Students;
// Уничтожение объекта
delete student;
return 0;
}
Gruvi вне форума   Ответить с цитированием
Старый 31.05.2013, 13:01   #13 (permalink)
Fenix
404
 
Аватар для Fenix
 
Регистрация: 10.01.2010
Сообщений: 1,749
Записей в дневнике: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 3868
По умолчанию

Рекурсия в С++ - Урок 11
recursive.png


Рекурсия это повторение элемента, подобного самому себе.

Рассмотрим на примере вычисления факториала.
Факториал - произведение чисел от 1 до n, включая n.
| 1 , n = 0;
n = |
| n * (n - 1), n > 0;

Пример:
6! = 1 * 1 * 2 * 3 * 4 * 5 * 6 = 720;

Напишем итеративный алгоритм для вычисления факториала:
Код:
    int factorial_iterative (int n)
	{
		if (n == 0)						// Если 0!
			return 1;					// то факториал = 1, возвращаем ее
		for (int i = n-1; i > 0; --i) 	// Декрименирующий цикл от (n - 1) до 0, не включая ноль
			n *= i;						// Производим умножение n и (n-1) членов последовательности

		return n;						// Возвращаем значение факториала
	}
Функция целочисленного типа. В качестве входного аргумента принимается целое число, возвращается значение факториала.
Вычисление факториала идет с декриминацией множителя: 6! = 6 * 5 * 4 * 3 * 2 * 1;
Данную функцию можно написать рекурсивно заменив цикл на рекурсию:
Код:
    int factorial_recursive (int n)
	{	
		if (n == 0) 							// Условие выхода: если n равно 0
			return 1;
	
		return n * factorial_recursive (n-1); 	// Возвращаем значение факториала
	}
Рекурсивная функция вызывает сама себя, пока условие выхода из нее не будет истинным.
В данном случае, функция в 5-ой строке будет вызывать сама себя с декрименацией аргумента, пока последний не станет нулем.
Рассмотрим работу алгоритма на примере 6!:
Код:
 	factorial_recursive (6):
	{	
	 if (6 == 0) 							
	  return 1;
	
	 return 6 * factorial_recursive (6-1)	
	   		    {	
				 if (5 == 0) 							
				  return 1;
				 return 5 * factorial_recursive (5-1)
				  			{	
							 if (4 == 0) 							
							  return 1;
							 return 4 * factorial_recursive (4-1)
							    		{	
										 if (3 == 0) 							
										  return 1;
							  			 return 3 * factorial_recursive (3-1)
										 	        {	
													 if (2 == 0) 							
													  return 1;
													 return 2 * factorial_recursive (2-1) 	
				   									  		    {	
																 if (1 == 0) 							
																  return 1;
																 return 1 * factorial_recursive (1-1)
							   											    {	
																			 if (0 == 0) 							
																			  return 1; // выход 	
				   									 					    } 	
				   												}
				   									} 	
				   						}	 	
				   			}
				 }	 	
	}
При написании рекурсивных функций сначала пишем условие выхода, а потом уже основной алгоритм.

Любой рекурсивный алгоритм можно реализовать итеративно.
Глубина рекурсии - количество вложеных вызовов самой себя в глубину. В нашем примере глубина рекурсии равна 5.
Рекурсивные алгоритмы короче, красивее, удобнее своих итерационных аналогов. Рекурсия не дает выиграша вы быстродействии
и даже дает небольшой проигрыш в использовании памяти. Для огромных объемов данных все же применяют итеративные алгоритмы.
Особо удачно использование рекурсии и рекурсивно-ориентироваными структурам, к примеру - деревья. Также удачно рекурсия
ложится на быструю сортировку методом Ч.Хоара (о ней будет статья в цикле "сортировки").

Код:
#include <iostream>
using namespace std;

long long int factorial_recursive (long long int n)
{
	if (n == 0) 
		return 1;
	
	return n * factorial_recursive (n-1);
}

long long int factorial_iterative (long long int n)
{
	if (n == 0)
		return 1;
	for (long long int i = n-1; i > 0; --i) 
		n *= i;

	return n;
}

int main ()
{
	long long int x;
	cout<<"Enter x: ";
	cin>>x;
	if (x < 0) {
		cout<<endl<<"Error! x must be non-negative!";
		return 0;		
	}
        if (x > 16) {
                cout<<endl<<"Error! n overflow!";
                return 0;



	cout<<endl<<"recursive factorial "<<x<<" = "<<factorial_recursive (x);
	cout<<endl<<"iterative factorial "<<x<<" = "<<factorial_iterative (x);
	return 0;
}
nieiie-yedhaia-io-2013-05-31-14-51-04.png
Примечание: В данном варианте максимальное значение x = 16, в противном случае - переполнение переменной n. Если изменить тип на long int предел x = 19, при long long int - 25. Дальнейшее увеличение верхней границы x требует использования длинной арифметики.
Компилятор: g++
Fenix вне форума   Ответить с цитированием
Старый 22.01.2017, 13:51   #14 (permalink)
MaximABC
Новичок
 
Регистрация: 22.01.2017
Сообщений: 1
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Так я не понял где продолжение?
MaximABC вне форума   Ответить с цитированием
Старый 12.12.2021, 23:19   #15 (permalink)
MisLove
Member
 
Регистрация: 12.12.2021
Сообщений: 21
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Можете в ютубе канал по с++ порекомендовать?
MisLove вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.




Часовой пояс GMT +4, время: 12:02.

Powered by vBulletin® Version 6.2.5.
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.