Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Легкое решение задач по математике и физике! Первое отличие С от С++



  2005-2006 Учебный физико-математический студенческий центр

Легкое решение задач по математике и физике! #7

      
 

Здравствуйте, уважаемые наши подписчики!

Главная
О нашей работе
Регистрация заказа
Запись на  курсы ЕГЭ
Стоимость работы
Способы оплаты
Обратная связь

 
Подпишитесь на нашу рассылку на Subscribe.Ru
Легкое решение задач по математике и физике!
 

logo 



  Для начала разрешите поздравить всех девушек с началом Весны,
     С Восьмым Марта!

В прошлый раз мы разобрали основы языка С++.
Давайте теперь углубимся в изучение языка.


Представляю Вам 7-ой выпуск рассылки.

Итак, чем же отличается С от С++?
Вообще говоря,
С это подмножество С++ и все вещи, которые Вы использовали в С будут работать и в С++, но многие из них уже не являются столько хорошими и подходящими под понятие "правильное программирование". С это довольно простой язык. Всё что в нём есть это макросы, указатели, структуры, массивы и функции. Не важно какая у вас проблема, решение всегда будет вращаться вокруг макросов, указателей, структур, массивов и функций. В С++ не так. Конечно все эти вещи здесь присутствуют, но тут также есть закрытые и защищённые члены класса, перегрузка функций, параметры по умолчанию, конструкторы, деструкторы, шаблоны, исключения, пространства имён и так далее. Пространство для размышления в С++ гораздо больше, чем в С. И это может неопытного разработчика приводить к замешательству. Сегодня Мы рассмотрим первое отличие С от С++.


Первое отличие С от С++
   предпочитайте const и inline вместо #define

Этот подзаголовок можно было бы также назвать "предпочитайте компилятор препроцессору", потому что #define это не часть языка per se (как таковая). По правде сказать это одна из его проблем :-). Когда Вы пишете что-то подобное:

#define ASPECT_RATIO 1.232

символическое имя ASPECT_RATIO не пишется компилятором в таблицу имён, потому что на этапе препроцессора оно заменяется в коде на число 1.232. И не дай бог Вы забыли инклудить файл с этим дефайном, Вы долго и мучительно будете вспоминать, что это за число такое.
Решение этой проблемы весьма простое:

const double ASPECT_RATIO = 1.232;

Эта штука работает! Однако здесь нельзя не упоминуть о двух вещах.
Первое. Чтобы определить константный указатель приходится немного хитрить. Например, Вам нужно завести строку, тогда Вам придётся писать
const дважды:

const char* const NAME = "Help-Studia";

и подробнее это будет обсуждаться в следующих выпусках рассылки.
Второе. Часто бывает очень удобно определить специфические для того или иного класса константы. Для этого нужно описать их в поле определения класса и убедиться, что у Вас будет только одна копия константы, для этого используйте
static.

class GamePlayer {
private:
 static const int NUM_TURNS = 5; // объявление константы
 int scores[NUM_TURNS]; // её использование

Однако тут есть небольшая неприятность. Поскольку это лишь объявление константы, то необходимо в тело С++ файла поместить и её определение.
const int GamePlayer::NUM_TURNS;
Но если вы об этом забудете, то не переживайте, компилятор напомнит Вам об этой мелочи.

Теперь вернёмся к препроцессору.
Другая проблемка заключается в том, что народ любит использовать макросы как функции:

#define max(a,b) ((a) > (b) ? (a) : (b))

Этот маленький дефайн имеет столько недостатков, что подумать страшно.
Мало того, что Вы должны постоянно помнить о скобках! Все аргументы должны браться в скобки, потому что если вы попытается вызвать
max для сложного выражения Вы попадёте в неприятности. Кроме того, рассмотрим небольшой пример:

int a = 5, b = 0;
max(++a, b);     // в это случае "a" инкрементируется дважды
max(++a, b+10);  // а в этом один раз

Таким образом, получается, что то что случится с
"a" зависит от того с чем она сравнивается!

К счастью расстраиваться не стоит. Потому что можно написать короткую функцию, а если использовать для её определения ключевое слово inline то никакого отличия от
define по скорости Вы не заметите, потому что её код будет вставляться в тело программы при каждом вызове.
inline int max(int a, int b) { return a > b ? a : b; }
Но что делать если Вы хотите использовать max не только для int, но и для double?
Ответ прост! Шаблоны! Они замечательно решают эту проблему:

template<class T>

inline const T& max (const T& a, const T& b) { return a > b ? a : b; }

Этот шаблончик сгенерит целое семейство функций. Если Вы вызовете max для ште, то ог инстанционируется int'ом. Если вызовете для double - то double'ом. А поскольку заранее тип аргумента не известен, то лучше его передавать по ссылке (T&). Это будет более быстро и эффективно, так как ссылка занимает 4 байта, а например double целых 8.


Для завершения рассылки приедём небольшую задачку, типчную для курсовых работ математических факультетов!
Требуется создать класс полиномов. Он должен обладать всеми основными операция сложения, умножения, сравнения и так далее. Так же написать небольшой тест-проверку для всех методов класса.

Код:

// отключаем ненужные предупреждения
#pragma warn -inl
#pragma warn -lvc

// подключаем необходимые системные библиотеки
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

// класс полином
class polynom {
 private:
   int s;         // степень полинома
   double *coefs; // коэффициенты
 public:
   polynom() {s = -1; coefs = NULL;};  // пустой конструктор
   polynom(int sf) {                   // конструктор по степени полинома
      s = sf;
      coefs = new double[s+1];
      for (int i=0; i<=s; i++) coefs[i] = 0.0;
   };
   polynom(polynom& copy) {            // конструктор копирования
      s = -1;
      coefs = NULL;
      *this = copy;
   };
   ~polynom() { if(coefs) delete[] coefs; }; // деструктор

   int stepen() {return s;}; // возвращает степень полинома

   // установаить коэффициент coef при степени sf
   void set(double coef, int sf) {
      // если заданная степень больше степени полинома, выходим
      if (sf>s) return;
      // иначе заносим в нужное место
      coefs[sf] = coef;
   };

   // возвращает коэффициент при степени sf
   double get(int sf) {
      // если заданная степень больше степени полинома, возвращаем ноль
      if (sf>s) return 0.0;
      // иначе соответствующий коэффициент
      return coefs[sf];
   };

   // вывод полинома на экран
   void print() {
      for (int i=s; i>=0; i--) {
         cout << coefs[i] << "*x^" << i;
         if (i!=0) cout << " + ";
      }
   };

   // оператор копирования
   polynom& operator= (polynom& copy) {
      if (coefs) delete[] coefs;
      s = copy.stepen();
      coefs  = new double[s+1];
      // копируем все коэффициенты
      for (int i=0; i<=s; i++) set(copy.get(i),i);
      return *this;
   };

   // оператор сложения
   polynom operator+ (polynom& a) {
      int max_s = a.stepen();
      if(max_s<s) max_s = s;
      polynom temp(max_s);
      // теперь складываем коэффициенты при соответствующих степенях
      for (int i=0; i<=max_s; i++) temp.set(get(i) + a.get(i), i);
      return temp;
   };

   // оператор вычитания
   polynom operator- (polynom& a) {
      int max_s = a.stepen();
      if(max_s<s) max_s = s;
      polynom temp(max_s);
      // теперь вычитаем коэффициенты при соответствующих степенях
      for (int i=0; i<=max_s; i++) temp.set(get(i) - a.get(i), i);
      return temp;
   };

   // оператор умножения
   polynom operator* (polynom& a) {
      int sf = a.stepen()+s;
      polynom temp(sf); // полином в который будем складывать результат
      for (int i=0; i<=a.stepen(); i++) {
         polynom ti(s+i); // временный полином для почленного перемножения
         for (int j=0; j<=s; j++)
            ti.set(get(j) * a.get(i),i+j); // почленное умножение
         temp += ti;
      }
      return temp;
   };

   // оператор +=
   polynom& operator+= (polynom& a) {
      *this = *this + a;
      return *this;
   };
   // оператор -=
   polynom& operator-= (polynom& a) {
      *this = *this - a;
      return *this;
   };
   // оператор *=
   polynom& operator*= (polynom& a) {
      *this = *this * a;
      return *this;
   };

};

int main()
{
   clrscr();
   int stepen = 0, i;
   cout << "Введите степень полинома A: "; cin >> stepen;
   polynom A(stepen);
   for (i=0; i<=stepen; i++) {
      double t;
      cout << "coef of " << i << ": ";
      cin >> t;
      A.set(t,i);
   };
   cout << endl;
   cout << "Введите степень полинома B: "; cin >> stepen;
   polynom B(stepen);
   for (i=0; i<=stepen; i++) {
      double t;
      cout << "coef of " << i << ": ";
      cin >> t;
      B.set(t,i);
   };

   cout << endl << "A = ";
   A.print();
   cout << endl << "B = ";
   B.print();

   polynom C;

   C = A + B; // сложение
   cout << endl << "A+B = ";
   C.print();


   C = A * B; // умножение
   cout << endl << "A*B = ";
   C.print();

   getche();
   return 0;
}

Работоспособность данной программы проверялась в среде Borland С++ 4.5

Решение подобных задач вы можете заказать на этой страничке.
 
2005-2007 help-studia andy kras




В избранное