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

Программирование - это легко!



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

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

      
 

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

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

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

logo 



  Для начала разрешите поздравить всех влюблённых
     с днём святого Валентина!

В прошлый раз мы с Вами решили задачи по аналитической геометрии.
Теперь попробуем отвлечься от математики и займёмся программированием. Мы с Вами будем изучать С++, поскольку это сейчас самый популярный язык в среде разработчиков программного обеспечения ориентированного на математиков и физиков.


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

Предпологается, что опыт программирования на С у Вас есть, но тем не менее основы языка С уважаемый подписчик может найти в предлагаемом материале. Я не зря подчёркиваю и говорю С, потому что С++ это не просто расширение языка С (которое, кстати, заключается в том, что вводится новое понятие: пользовательский тип - классы). Это другая идеология программирования. Вместо процедурного программирования в С, на смену приходит программирование в классах С++. Мы будем рассматривать эффективность С++, так сказать анатомию языка. Также коснёмся STL. (стандартной библиотеки шаблонов) и правилов хорошего программирования на вообщем-то любом языке, в том числе и на С++.


Транслятор и компоновщик
Начнём с небольших пояснений. Программа - это последовательность инструкций, предназначенных для выполнения компьютером. Программы оформляются в виде текста, который записывается в файлы. Этот текст является результатом деятельности программиста, т.е. Вас!
Но чтобы компьютер понял Ваши инструкции их необходимо перевести на его язык. А для этого существуют две программы: препроцессор и компилятор. Обычно они объединены в одну и называются средой программиста. Например, Visual Studio .net или Borland С++.
Итак, что же такое препроцессор? Это программа, которая собирает Ваш код в один большой файл, если он состоит из нескольких файлов с расширением h и одного файла cpp. Для этого существует директива препроцессора #include <имя_файла>. Затем, компилятор превращает Ваш код в объектный файлы, которые уже затем автоматически линкуются в исполняемый (exe) файл.

Алфавит C++

Алфавит С++ включает:

  • строчные и прописные буквы латинского алфавита (мы их будем называть буквами),
  • цифры от 0 до 9 (назовём их буквами-цифрами),
  • символ '_' (подчерк - также считается буквой),
  • набор специальных символов:
    " { } , | [ ] + - % / \ ; ' : ? < > = ! & # ~ ^ . *
  • прочие символы.

Алфавит С++ служит для построения слов, которые в С++ называются лексемами. Различают пять типов лексем:

  • идентификаторы,
  • ключевые слова,
  • знаки (символы) операций,
  • литералы,
  • разделители.

Почти все типы лексем (кроме ключевых слов и идентификаторов) имеют собственные правила словообразования, включая собственные подмножества алфавита.

Правила образования идентификаторов (имена переменных)

  1. Первым символом идентификатора С++ может быть только буква.
  2. Следующими символами идентификатора могут быть буквы, буквы-цифры и буквы-подчерки.
  3. Длина идентификатора неограниченна (фактически же длина зависит от реализации системы программирования).

Типы
Тип является основной характеристикой объекта и функции. К целочисленным типам относятся типы, представленные следующими именами основных типов:

char
short
int
long

Имена целочисленных типов могут использоваться в сочетании с парой модификаторов типа:

signed
unsigned

Для Borland С++ 4.5, основные характеристики целочисленных типов выглядят следующим образом:

Тип данных Байты Биты Min Max
signed char 1 8 - 128 127
unsigned char 1 8 0 255
signed short 2 16 -32768 32767
enum 2 16 -32768 32767
unsigned short 2 16 0 65535
signed int 2 16 -32768 32767
unsigned int 2 16 0 65535
signed long 4 32 -2147483648 2147483647
unsigned long 4 32 0 4294967295

К плавающим типам относятся три типа, представленные следующими именами типов, модификаторов и их сочетаний:

float
double
long double

Ниже представлены основные характеристики типов данных с плавающей точкой (опять же для Borland С++ 4.5):

Тип данных Байты Биты Min Max
float 4 32 3.4E-38 3.4E+38
double 8 64 1.7E-308 1.7E+308
long double 10 80 3.4E-4932 3.4E+4932

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


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

Код:

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

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

// класс прямоугольной матрицы MxN
class matrix {
 private:
   int m;         // высота
   int n;         // ширина
   double *data;  // элементы матрицы
 public:
   matrix() {m = n = 0; data = NULL;}; // пустой конструктор
   matrix(int M, int N) { // конструктор по размерам матрицы
      m = M;
      n = N;
      data = new double[m*n]; // выделяем память
      for (int i=0; i<m*n; i++) data[i] = 0.0; // заполняем нулями все элементы
   };
   matrix(int M, int N, double val) { // конструктор по размерам матрицы и по значению
      m = M;
      n = N;
      data = new double[m*n]; // выделяем память
      for (int i=0; i<m*n; i++) data[i] = val; // заполняем числом val всю матрицу
   };
   matrix(matrix& copy) { // конструктор копирования
      data = NULL;
      *this = copy;
   };
   ~matrix() { if(data) delete[] data; }; // деструктор

   // operator скобки, чтобы получить значение элемента по i, j
   double& operator() (int i, int j) {
      if (i>=m || j>=n) return data[0]; // i, j выходят за пределы матрицы
      return data[i*n + j]; // сдвинулись на i строк и взяли j-ый элемент
   };


   // вывод матрицы на экран
   void show() {
      for (int j=0; j<m; j++) {
         for (int i=0; i<n; i++)
            cout << data[j*n + i] << " ";
            if (j+1!=m) cout << endl;
      }
   };

   // оператор копирования
   matrix& operator= (matrix& copy) {
      m = copy.m;
      n = copy.n;
      if (data) delete[] data; // уничтожаем старую память
      data  = new double[n*m]; // выделяем новую память
      for (int i=0; i<n*m; i++) data[i] = copy.data[i]; // копируем все элементы
      return *this;
   };

   // оператор сложения
   matrix operator+ (matrix& a) {
      matrix temp(*this); // создаём временную матрицу, копия матрицы *this
      for (int i=0; i<a.m*a.n; i++) temp.data[i] += a.data[i]; // прибавляем к *this (текущей матрицы) входящую матрицу a
      return temp;
   };

   // оператор вычитания
   matrix operator- (matrix& a) {
      matrix temp(*this); // создаём временную матрицу, копия матрицы *this
      for (int i=0; i<a.m*a.n; i++) temp.data[i] -= a.data[i]; // вычитаем из текущей матрицы входящую матрицу a
      return temp;
   };

   // оператор умножения
   matrix operator* (matrix& a) {
      int M = m;
      if (m<n) M = n; // вычисляем что больше ширина или высота
      // в M хранится максимальное значение
      int N = M;
      matrix temp(M,N); // создаём временную матрицу, куда будем ложить результат перемножения матриц *this и a
      for (int i=0; i<M; i++)
         for (int j=0; j<N; j++) {
            double sum = 0;
            if (n<m) { // если n<m, то перемножаем столбец матрицы *this на строку матрицы a
               for (int y=0; y<n; y++)
                  sum += (*this).operator()(j,y) * a(y,i); // результат суммируем
            } else { // если n>m, то перемножаем строку матрицы *this на столбец матрицы a
               for (int y=0; y<m; y++)
                  sum += (*this).operator()(y,j) * a(i,y);
       }
       temp(i,j) = sum; // затем сумму ложим в результирующую матрицу на место i, j
    }
      return temp;
   };

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

};

int main()
{
   // создаём матрицы
   matrix A(2,4,1.0); A(0,0) = 2; A(1,1) = 2; A(0,1) = 2;
   matrix B(4,2,3.0); B(0,0) = 1; B(1,1) = 2; B(0,1) = 2;
   matrix C(4,4);

   C = A * B; // перемножаем

   clrscr();
   cout << endl << "умножение матриц:" << endl;
   A.show();
   cout << endl << "*" << endl;
   B.show();
   cout << endl << "=" << endl;
   C.show();
   getche();

   // создаём матрицы для сложения
   matrix s1(3,2,3.14);
   matrix s2(3,2,2.71);
   s1(0,0) = 2.71; s1(1,1) = 2.71; s1(2,0) = 2.71;
   s2(0,0) = 3.14; s2(1,1) = 3.14; s2(2,0) = 3.14;
   matrix s;
   s = s1 + s2; // складываем

   clrscr();
   cout << endl << "сложение матриц:" << endl;
   s1.show();
   cout << endl << "+" << endl;
   s2.show();
   cout << endl << "=" << endl;
   s.show();
   getche();

   // создаём матрицы для вычитания
   matrix e1(3,2,3.14);
   matrix e2(3,2,2.71);
   e1(0,0) = 2.71; e1(1,1) = 2.71; e1(2,0) = 2.71;
   e2(0,0) = 3.14; e2(1,1) = 3.14; e2(2,0) = 3.14;
   matrix e;
   e = e1 - e2; // складываем

   clrscr();
   cout << endl << "вычитание матриц:" << endl;
   e1.show();
   cout << endl << "-" << endl;
   e2.show();
   cout << endl << "=" << endl;
   e.show();
   getche();

   return 0;
}

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

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




В избранное