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

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

Книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!

291 0 18:03, 26-08-2023
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
26 август 2023

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

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

    1 ... 282 283 284 285 286 287 288 289 290 ... 337
    Перейти на страницу:
    (функция fopen() — это стандартный способ открытия файла в языке C). Мы могли бы упростить работу тестировщиков, если бы просто написали следующий код:

    void do_resources2(int a, int b, const char* s) // менее плохой код

    {

      ifstream is(s);            // открываем файл

      vector<int>v1(a);          // создаем вектор (выделяем память)

      if (b<=0) throw Bad_arg(); // может генерировать исключение

      vector<int> v2(b);         // создаем другой вектор (выделяем память)

    }

     

     Теперь каждый ресурс принадлежит объекту и освобождается его деструктором. Иногда, чтобы выработать идеи для тестирования, полезно попытаться сделать функцию более простой и ясной. Общую стратегию решения задач управления ресурсами обеспечивает метод RAII (Resource Acquisition Is Initialization — получение ресурса есть инициализация), описанный в разделе 19.5.2.

     

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

    FILE* do_resources3(int a, int* p, const char* s) // плохая функция

                                       // неправильная передача ресурса

    {

      FILE* f = fopen(s,"r");

      delete p;

      delete var;

      var = new int[27];

      return f;

    }

    Правильно ли, что функция do_resources3() передает (предположительно) открытый файл обратно как возвращаемое значение? Правильно ли, что функция do_resources3() освобождает память, передаваемую ей как аргумент p? Мы также добавили действительно коварный вариант использования глобальной переменной var (очевидно, указатель). В принципе передача ресурсов в функцию и из нее является довольно распространенной и полезной практикой, но для того чтобы понять, корректно ли выполняется эта операция, необходимо знать стратегию управления ресурсами. Кто владеет ресурсом? Кто должен его удалять/освобождать? Документация должна ясно и четко отвечать на эти вопросы. (Помечтайте.) В любом случае передача ресурсов изобилует возможностями для ошибок и представляет сложность для тестирования.

     

     Обратите внимание на то, что мы (преднамеренно) усложнили пример управления ресурсами, использовав глобальную переменную. Если в программе перемешано несколько источников ошибок, ситуация может резко ухудшиться. Как программисты мы стараемся избегать таких ситуаций. Как тестировщики — стремимся найти их.

    26.3.3.3. Циклы

     

     Мы уже рассматривали циклы, когда обсуждали функцию binary_search().

    Большинство ошибок возникает в конце циклов.

    • Правильно ли проинициализированы переменные в начале цикла?

    • Правильно ли заканчивается цикл (часто на последнем элементе)?

    Приведем пример, который содержит ошибку.

    int do_loop(const vector<int>& v) // плохая функция

                                      // неправильный цикл

    {

      int i;

      int sum;

      while(i<=vec.size()) sum+=v[i];

      return sum;

    }

    Здесь содержатся три очевидные ошибки. (Какие именно?) Кроме того, хороший тестировщик немедленно выявит возможности для переполнения при добавлении чисел к переменной sum.

     

     Многие циклы связаны с данными и могут вызвать переполнение при вводе больших чисел.

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

    char buf[MAX];    // буфер фиксированного объема

    char* read_line() // опасная функция

    {

      int i = 0;

      char ch;

      while(cin.get(ch) && ch!='n') buf[i++] = ch;

      buf[i+1] = 0;

      return buf;

    }

    Разумеется, вы не написали бы ничего подобного! (А почему нет? Что плохого в функции read_line()?) Однако эта ошибка, к сожалению, является довольно распространенной и имеет разные варианты.

    // опасный фрагмент

    gets(buf);       // считываем строку в переменную buf

    scanf("%s",buf); // считываем строку в переменную buf

     

     Поищите описание функций gets() и scanf() в своей документации и избегайте их как чумы. Под словом “опасная” мы понимаем, что переполнение буфера является инструментом для взлома компьютеров. В настоящее время реализации выдают предупреждение об опасности использования функции gets() и ее аналогов.

    26.3.3.4. Ветвление

     

     Очевидно, что, делая выбор, мы можем принять неправильное решение. Из-за этого инструкции if и switch являются одними из основных целей для тестировщиков. Существуют две проблемы, которые необходимо исследовать.

    • Все ли возможные варианты предусмотрены?

    • Правильные ли действия связаны с правильными вариантами выбора?

    Рассмотрим следующую бессмысленную функцию:

    void do_branch1(int x, int y) // плохая функция

        // неправильное использование инструкции if

    {

      if (x<0) {

        if (y<0)

          cout << "Большое отрицательное число n";

        else

          cout << "Отрицательное число n";

      }

      else if (x>0) {

        if (y<0)

          cout << "Большое положительное число n";

        else

          cout << "Положительное число n";

      }

    }

    Наиболее очевидная ошибка в этом фрагменте заключается в том, что мы забыли о варианте, в котором переменная x равна нулю. Сравнивая числа (положительные или отрицательные) с нулем, программисты часто забывают о нем или приписывают неправильной ветви (например, относят его к отрицательным числам). Кроме того, существует более тонкая (хотя и распространенная) ошибка, скрытая в этом фрагменте: действия при условиях (x>0 && y<0) и (x>0 && y>=0) каким-то образом поменялись местами. Это часто случается, когда программисты пользуются командами “копировать и вставить”.

    Чем более сложными являются варианты использования инструкций if, тем вероятнее становятся ошибки. Тестировщики анализируют такие коды и стараются не пропустить ни одной ветви. Для функции do_branch1() набор тестов очевиден.

    do_branch1(–1,–1);

    do_branch1(–1, 1);

    do_branch1(1,–1);

    do_branch1(1,1);

    do_branch1(–1,0);

    do_branch1(0,–1);

    do_branch1(1,0);

    do_branch1(0,1);

    do_branch1(0,0);

    По существу, это наивный подход “перебора всех альтернатив”, которой мы применили, заметив, что функция do_branch1() сравнивает значения с нулем с помощью операторов < и >. Для того чтобы выявить неправильные действия при положительных значениях переменной x, мы должны объединить вызовы функции с желаемыми результатами.

    Обработка инструкций switch аналогична обработке инструкций if.

    void do_branch1(int x, int y)  // плохая функция

     // неправильное

    1 ... 282 283 284 285 286 287 288 289 290 ... 337
    Перейти на страницу:
    1. Жалоба
    Отзывы - 0

    Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.


    Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

    • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
    • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
    • 3. Просьба отказаться от нецензурной лексики.
    • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

    Надеемся на Ваше понимание и благоразумие. С уважением, администратор LoveRead.info.


    Установить VPN и читай слушай бесплатно

    Новые отзывы

    1. Людмила Хофман Людмила Хофман10 июнь 22:13 У меня перевернулся мир после прочтения ваших книг! Так приятно и чисто на душе, ведь по сути неважно кто с кем , а только любовь... Долгая игра - Рейчел Рид
    2. Анна Анна08 июнь 11:28 Спасибо за новую историю жизни и любви на сайте,прочитала с удовольствием .... Давай поженимся - Юлия Резник
    3. Елена Елена08 июнь 11:13 Прочла несколько романов этого, без сомнения, талантливого автора. Впечатление прекрасное, но хотелось бы когда-нибудь прочесть... Предатель. Ты врал мне годами - Арина Арская
    Все комметарии
    Новинки бесплатной онлайн библиотеки