Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Aliens Vs Predator |#6| We walk through the tunnels
Aliens Vs Predator |#5| Unexpected meeting
Aliens Vs Predator |#4| Boss fight with the Queen
Aliens Vs Predator |#3| Escaping from the captivity of the xenomorph

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Страустрап Б. Весь текст 579.17 Kb

Язык С++

Предыдущая страница Следующая страница
1 ... 12 13 14 15 16 17 18  19 20 21 22 23 24 25 ... 50
целое, то

  if (a) // ...

эквивалентно

  if (a != 0) // ...

  Логические операции

  &&    ||    !

наиболее часто  используются в  условиях. Операции && и || не будут
вычислять второй аргумент, если это ненужно. Например:

  if (p && 1count) // ...

вначале проверяет,  является ли  p не нулем, и только если это так,
то проверяет 1count.
  Некоторые простые  операторы if  могут быть  с удобством заменены
выражениями арифметического if. Например:

  if (a <= d)
      max = b;
  else
      max = a;

лучше выражается так:

  max = (a<=b) ? b : a;

Скобки вокруг  условия необязательны,  но я  считаю, что  когда они
используются, программу легче читать.
  Некоторые простые  операторы switch  можно по-другому  записать в
виде набора операторов if. Например:

                             - стр 102 -

  switch (val) {
  case 1:
      f();
      break;
  case 2;
      g();
      break;
  default:
      h();
      break;
  }

иначе можно было бы записать так:

  if (val == 1)
      f();
  else if (val == 2)
      g();
  else
      h();

  Смысл тот  же, однако  первый вариант  (switch) предпочтительнее,
поскольку  в   этом  случае   явно  выражается   сущность  действия
(сопоставление значения  с рядом констант). Поэтому в нетривиальных
случаях оператор switch читается легче.
  Заботьтесь о  том, что  switch должен  как-то  завершаться,  если
только вы не хотите, чтобы выполнялся следующий case. Например:

  switch (val) {    // осторожно
  case 1:
      cout << "case 1\n";
  case 2;
      cout << "case 2\n";
  default:
      cout << "default: case не найден\n";
  }

при val==1 напечатает

  case 1
  case 2
  default: case не найден

к великому изумлению непосвященного. Самый обычный способ завершить
случай - это break, иногда можно даже использовать goto. Например:

                             - стр 103 -

  switch (val) {    // осторожно
  case 0:
      cout << "case 0\n";
  case1:
  case 1:
      cout << "case 1\n";
      return;
  case 2;
      cout << "case 2\n";
      goto case1;
  default:
      cout << "default: case не найден\n";
      return;
  }

При обращении к нему с val==2 выдаст

  case 2
  case 1

Заметьте, что  метка case  не подходит как метка для употребления в
операторе goto:

  goto case 1;        // синтаксическая ошибка

     3.3.2 Goto

  C++ снабжен имеющим дурную репутацию оператором goto.

  goto идентификатор;
  идентификатор : оператор

  В общем,  в программировании  высокого уровня он имеет очень мало
применений, но  он может  быть очень  полезен, когда  C++ программа
генерируется программой,  а не  пишется непосредственно  человеком.
Например,  операторы   goto  можно  использовать  в  синтаксическом
анализаторе, порождаемом  генератором синтаксических  анализаторов.
Оператор goto  может быть  также важен  в тех редких случаях, когда
важна наилучшая эффективность, например, во внутреннем цикле какой-
нибудь программы, работающей в реальном времени.
  Одно  из   немногих  разумных  применений  состоит  в  выходе  из
вложенного  цикла   или  переключателя   (break   лишь   прекращает
выполнение  самого   внутреннего  охватывающего   его   цикла   или
переключателя). Например:

  for (int i = 0; i
3.4 Комментарии и Выравнивание

  Продуманное   использование    комментариев    и    согласованное
использование отступов  может сделать  чтение и понимание программы
намного  более  приятным.  Существует  несколько  различных  стилей
согласованного  использования  отступов.  Автор  не  видит  никаких
серьезных  оснований   предпочесть  один  другому  (хотя  как  и  у
большинства, у  меня есть  свои предпочтения).  Сказанное относится
также и к стилю комментариев.
  Неправильное использование  комментариев может  серьезно повлиять
на удобочитаемость  программы, Компилятор  не  понимает  содержание
комментария, поэтому  он никаким способом не может убедиться в том,
что комментарий
  [1] осмыслен;
  [2] описывает программу; и
  [3] не устарел.
  Непонятные,  двусмыленные   и  просто   неправильные  комментарии
содержатся в  большинстве программ.  Плохой комментарий  может быть
хуже, чем никакой.
  Если что-то можно сформулировать средствами самого языка, следует
это сделать,  а не  просто отметить в комментарии. Данное замечание
относится к комментариям вроде:

  // переменная "v" должна быть инициализирована.

  // переменная "v" должна использоваться только функцией "f()".

  // вызвать функцию init() перед вызовом
  // любой другой функции в этом файле.

  // вызовите функцию очиститки "cleanup()" в конце вашей
  программы.

  // не используйте функцию "wierd()".

  // функция "f()" получает два параметра.

При правильном  использовании C++  подобные комментарии как правило
становятся ненужными. Чтобы предыдущие комментарии стали излишними,
можно,  например,   использовать  правила   компоновки   (#4.2)   и
видимость,  инициализацию   и  правила  очистки  для  классов  (см.
#5.5.2).
  Если  что-то  было  ясно  сформулировано  на  языке,  второй  раз
упоминать это в комментарии не следует. Например:

  a = b+c;    // a становится b+c
  count++;    // увеличить счетчик

Такие комментарии  хуже чем  просто излишни,  они увеличивают объем
текса, который  надо прочитать,  они часто  затуманивают  структуру
программы, и они могут быть неправильными.
  Автор предпочитает:

                             - стр 105 -

  [1] Комментарий для каждого исходного файла, сообщающий, для чего
     в целом  предназначены находящиеся  в нем  комментарии, дающий
     ссылки на  справочники и  руководства, общие  рекомендации  по
     использованию и т.д.;
  [2] Комментарий  для  каждой  нетривиальной  функции,  в  котором
     сформулировано ее  назначение, используемый  алгоритм (если он
     неочевиден)  и,   быть  может,  что-то  о  принимаемых  в  ней
     предположениях относительно среды выполнения;
  [3] Небольшое число  комментариев в  тех  местах,  где  программа
     неочевидна и/или непереносима; и
  [4] Очень мало что еще.
  Например:

  // tbl.c: Реализация таблицы имен
  /*
      Гауссовское исключение с частичным
      См. Ralston: "A first course ..." стр. 411.
  */

  // swap() предполагает размещение стека AT&T sB20.

  /**************************************

      Copyright (c) 1984 AT&T, Inc.
      All rights reserved

  ****************************************/

  Удачно подобранные и хорошо написанные комментарии - существенная
часть программы. Написание хороших комментариев может быть столь же
сложным, сколь и написание самой программы.
  Заметьте также,  что если  в функции  используются  исключительно
комментарии //,  то любую часть этой функции можно закомментировать
с помощью комментариев /* */, и наоборот.

     3.5 Упражнения

  1. (*1) Перепишите  следующий оператор  for в виде эквивалентного
     оператора while:

       for (i=0; im
       *p.m
       *a[i]

  7. (*2)  Напишите функции:  strlen(),  которая  возвращает  длину
     строки, strcpy(),  которая копирует  одну строку  в другую,  и
     strcmp(), которая  сравнивает две  строки. Разберитесь,  какие
     должны быть  типы параметров  и типы  возвращаемых значений, а
     потом сравните  их со стандартными версиями, которые описаны в
      и в вашем руководстве.
  8. (*1) Посмотрите, как ваш компилятор реагирует на ошибки:

       a := b+1;
       if (a = 3) // ...
       if (a&077 == 0) // ...

     Придумайте ошибки попроще, и посмотрите, как компилятор на них
     реагирует.
  9. (*2)  Напишите   функцию  cat(),   получающую  два   строковых
     параметра   и    возвращающую   строку,    которая    является
     конкатенацией параметров.  Используйте new, чтобы найти память
     для  результата.  Напишите  функцию  rev(),  которая  получает
     строку и  переставляет в  ней символы  в обратном  порядке. То
     есть,  после  вызова  rev(p)  последний  символ  p  становится
     первым.
  10. (*2) Что делает следующая программа?

                             - стр 107 -

       void send(register* to, register* from, register count)
       // Полезные комментарии несомненно уничтожены.
       {
           register n=(count+7)/8;
           switch (count%8) {
               case 0: do {    *to++ = *from++;
               case 7: do {    *to++ = *from++;
               case 6: do {    *to++ = *from++;
               case 5: do {    *to++ = *from++;
               case 4: do {    *to++ = *from++;
               case 3: do {    *to++ = *from++;
               case 2: do {    *to++ = *from++;
               case 1: do {    *to++ = *from++;
                   while (--n>0);
           }
       }

     Зачем кто-то мог написать нечто похожее?
  11. (*2)  Напишите   функцию  atoi(),  которая  получает  строку,
     содержащую  цифры, и возвращает соответствующее int. Например,
     atoi("123") -  это 123. Модифицируйте atoi() так, чтобы помимо
     обычной  десятичной   она  обрабатывала   еще  восьмеричную  и
     шестнадцатиричную записи  C++. Модифицируйте atoi() так, чтобы
     обрабатывать запись  символьной  константы.  Напишите  функцию
     itoa(), которая  строит представление  целого параметра в виде
     строки.
  12. (*2) Перепишите  get_token() (#3.1.2),  чтобы она за один раз
     читала строку  в буфер,  а  затем  составляла  лексемы,  читая
     символы из буфера.
  13. (*2)  Добавьте   в  настрольный  калькулятор  из  #3.1  такие
     функции, как  sqrt(), log() и sin(). Подсказка: предопределите
     имена и  вызывайте функции  с помощью  вектора  указателей  на
     функции. Не забывайте проверять параметры в вызове функции.
  14. (*3)  Дайте пользователю  возможность  определять  функции  в
     настольном калькуляторе.  Подсказка: определяйте  функции  как
     последовательность  действий,   прямо  так,   как  их   набрал
     пользователь. Такую  последовательность можно  хранить или как
     символьную строку,  или как  список лексем. После этого, когда
     функция вызывается, читайте и выполняйте эти действия. Если вы
     хотите, чтобы  пользовательская функция получала параметры, вы
     должны придумать форму записи этого.
  15. (*1.5) Преобразуйте  настольный калькулятор так, чтобы вместо
     статических    переменных     name_string    и    number_value
     использовалась структура символа symbol:

       struct symbol {
           token_value tok;
           union {
               double number_value;
               char* name_string;
           };
       };

  16. (*2.5) Напишите программу, которая выбрасывает комментарии из
     C++ программы.  То есть,  читает из  cin, удаляет  // и  /* */
     комментарии и пишет результат в cout. Не заботьтесь о приятном

                             - стр 108 -

     виде выходного текста (это могло бы быть другим, более сложным
     упражнением).  Не   беспокойтесь  о   правильности   программ.
     Остерегайтесь //  и /*  и  */  внутри  комментариев,  строк  и
     символьных констант.
  17. (*2) Посмотрите  какие-нибудь программы, чтобы понять принцип
     различных  стилей   комментирования  и  выравнивания,  которые
     используются на практике.


                           Глава 4

                          Функции и Файлы

                                     Итерация свойственна человеку,
                                               рекусия божественна.
                                                    - Л. Питер Дойч

  Все нетривиальные  программы собираются  из нескольких  раздельно
компилируемых единиц  (их принято  называть просто файлами). В этой
главе  описано,   как  раздельно  откомпилированные  функции  могут
обращаться  друг   к  другу,  как  такие  функции  могут  совместно
пользоваться данными  (разделять данные),  и как  можно  обеспечить
Предыдущая страница Следующая страница
1 ... 12 13 14 15 16 17 18  19 20 21 22 23 24 25 ... 50
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (4)

Реклама