» » » » Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

На нашем литературном портале можно бесплатно читать книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп, Бьёрн Страуструп . Жанр: Программирование. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале litmir.org.
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Название: Программирование. Принципы и практика использования C++ Исправленное издание
Дата добавления: 22 август 2024
Количество просмотров: 100
Читать онлайн

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту readbookfedya@gmail.com для удаления материала

Программирование. Принципы и практика использования C++ Исправленное издание читать книгу онлайн

Программирование. Принципы и практика использования C++ Исправленное издание - читать бесплатно онлайн , автор Бьёрн Страуструп

Специальное издание самой читаемой и содержащей наиболее достоверные сведения книги по C++. Книга написана Бьярне Страуструпом — автором языка программирования C++ — и является каноническим изложением возможностей этого языка.
Помимо подробного описания собственно языка, на страницах книги вы найдете доказавшие свою эффективность подходы к решению разнообразных задач проектирования и программирования. Многочисленные примеры демонстрируют как хороший стиль программирования на С-совместимом ядре C++, так и современный -ориентированный подход к созданию программных продуктов. Третье издание бестселлера было существенно переработано автором. Результатом этой переработки стала большая доступность книги для новичков. В то же время, текст обогатился сведениями и методиками программирования, которые могут оказаться полезными даже для многоопытных специалистов по C++. Не обойдены вниманием и нововведения языка: стандартная библиотека шаблонов (STL), пространства имен (namespaces), механизм идентификации типов во время выполнения (RTTI), явные приведения типов (cast-операторы) и другие.
Настоящее специальное издание отличается от третьего добавлением двух новых приложений (посвященных локализации и безопасной обработке исключений средствами стандартной библиотеки), довольно многочисленными уточнениями в остальном тексте, а также исправлением множества опечаток.
Книга адресована программистам, использующим в своей повседневной работе C++. Она также будет полезна преподавателям, студентам и всем, кто хочет ознакомиться с описанием языка «из первых рук».

Перейти на страницу:
double) будет нарисован в окне. Второй и третий аргументы задают диапазон изменения переменной x (аргумента изображаемой функции). Четвертый аргумент (в данном случае orig) сообщает объекту класса Function, в каком месте окна расположено начало координат (0,0).

 

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

 

 Мы всегда стараемся сделать так, чтобы графики были понятны без дополнительных разъяснений. Люди не всегда читают текст, окружающий рисунок, поэтому он часто оказывается бесполезным. Все, что мы изображаем на рисунках, должно помочь читателям понять его. В данном случае мы просто ставим на каждом графике метку. Код для создания метки задается тремя объектами класса Text (см. раздел 13.11).

Text ts(Point(100,y_orig–40),"one");

Text ts2(Point(100,y_orig+y_orig/2–20),"x/2");

Text ts3(Point(x_orig–100,20),"x*x");

win.set_label("Function graphing: label functions");

win.wait_for_button();

С этого момента на протяжении всей главы мы будем пропускать повторяющийся код, связывающий фигуру с окном, присваивающий ей метку и ожидающий щелчка на кнопке Next.

 

 Тем не менее этот рисунок еще нельзя считать законченным. Мы уже отметили, что наклонная линия x/2 касается параболы x*x в точке (0,0), а график функции one пересекает линию x/2 в точке (2,1), но это известно лишь нам; для того чтобы это стало очевидно читателям, на рисунке следует нанести оси координат.

Код для построения осей состоит из объявлений двух объектов класса Axis (раздел 15.4).

const int xlength = xmax–40; // оси должны быть чуть меньше окна

const int ylength = ymax–40;

Axis x(Axis::x,Point(20,y_orig), xlength,

     xlength/x_scale, "one notch == 1");

Axis y(Axis::y,Point(x_orig, ylength+20),

     ylength, ylength/y_scale, " one notch == 1");

Использование значения xlength/x_scale в качестве параметра, задающего количество делений, позволяет использовать целочисленные отметки 1, 2, 3 и т.д. Выбор точки (0,0) в качестве начала координат является общепринятым. Если хотите, чтобы начало координат было не в центре, а, как обычно, в левом нижнем углу окна (раздел 15.6), вы легко сможете сделать это. Кроме того, для того чтобы различать оси, можно использовать цвет.

x.set_color(Color::red);

y.set_color(Color::red);

Итак, получаем результат, показанный ниже.

 

 Такой рисунок вполне приемлем, но по эстетическим причинам стоило бы сдвинуть линии немного вниз. Кроме того, было бы неплохо отодвинуть метки оси x немного влево. Однако мы не будем этого делать, поскольку эстетический вид графика можно обсуждать до бесконечности. Одно из профессиональных качеств программиста заключается в том, чтобы знать, когда остановиться и потратить сэкономленное время на что-нибудь более полезное (например, на изучение новых методов или на сон). Помните: “лучшее — враг хорошего”.

15.3. Класс Function

Определение класса графического интерфейса Function приведено ниже.

struct Function:Shape {

  // параметры функции не хранятся

 Function(Fct f,double r1,double r2,Point orig,

          int count = 100,double xscale = 25,double yscale = 25);

};

Класс Function является производным от класса Shape. Конструктор класса Function генерирует множество отрезков линий и хранит их в членах класса Shape. Эти отрезки линий аппроксимируют значения функции f. Значения функции f вычисляются count раз в точках, равномерно распределенных по интервалу [r1:r2].

Function::Function(Fct f,double r1,double r2,Point xy,

                   int count,double xscale,double yscale)

  // строит график функции f(x) для x из диапазона [r1:r2),

  // используя count отрезков линий;

  // начало координат (0,0) располагается в точке xy

  // координаты x масштабируются множителем xscale

  // координаты y масштабируются множителем yscale

{

  if (r2–r1<=0) error("Неправильный диапазон");

  if (count <=0) error("Отрицательное значение count");

  double dist = (r2–r1)/count;

  double r = r1;

  for (int i = 0; i<count; ++i) {

    add(Point(xy.x+int(r*xscale),xy.y–int(f(r)*yscale)));

    r += dist;

  }

}

Параметры xscale и yscale используются для масштабирования координат x и y соответственно. Обычно масштабирование необходимо для того, чтобы правильно расположить рисунок в окне.

Обратите внимание на то, что объект класса Function не хранит значения, передаваемые его конструктору, поэтому мы не можем впоследствии запросить у функции информацию о том, где находится начало координат, или перерисовать график с другими масштабирующими множителями. Этот объект просто хранит точки (в классе Shape) и выводит график на экран. Если бы мы хотели повысить гибкость объекта класса Function после его создания, то должны были бы хранить в нем требуемые значения (см. упр. 2). 

15.3.1. Аргументы по умолчанию

Обратите внимание на способ инициализации аргументов xscale и yscale конструктора класса Function. Такой способ инициализации называют заданием аргументов по умолчанию (default arguments). Их значения используются тогда, когда при вызове значения аргументов вообще не указываются.

Function s(one,r_min,r_max,orig,n_points,x_scale,y_scale);

Function s2(slope,r_min,r_max,orig,n_points,x_scale); // нет

                                                      // yscale

Function s3(square,r_min,r_max,orig,n_points);  // нет xscale,

                                                // нет yscale

Function s4(sqrt,r_min,r_max,orig); // нет count, нет xscale,

                                    // нет yscale

Этот фрагмент кода эквивалентен следующему:

Function s(one,r_min,r_max,orig,n_points,x_scale,y_scale);

Function s2(slope,r_min,r_max,orig,n_points,x_scale, 25);

Function s3(square,r_min,r_max,orig,n_points,25,25);

Function s4(sqrt,r_min,r_max,orig,100,25,25);

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

struct Function:Shape { // альтернатива аргументам, заданным

                        // по умолчанию

  Function(Fct f,double r1,double r2,Point orig,

  int count, double xscale,double yscale);

  // масштаб переменной y по умолчанию:

  Function(Fct f,double r1,double r2,Point orig,

  int count, double xscale);

  // масштаб переменной x и y:

  Function(Fct f,double r1,double r2,Point orig,int count);

  // значение count по умолчанию и

Перейти на страницу:
Комментариев (0)