воскресенье, 17 июля 2011 г.

настройка Vim

Для перехода на новую строку с отступом предыдущей строки

set smartindent

в файле vimrc

суббота, 16 июля 2011 г.

Установка QNX Neutrino (Шаг 2)

Для написание программ которые будут запускаться на QNX Neutrino Realtime Operating System (RTOS) во-первых вам потребуется QNX Software Development Platform (SDP), которая была установлена в предыдущей части. Так же вам понадобится установленная QNX Neutrino для запуска написанных вами программ. Существует несколько вариантов установки операционной системы QNX Neutrino. Все они детально описаны в официальном руководстве по установке здесь.

вторник, 12 июля 2011 г.

QNX Momentics IDE (Шаг 1)

             QNX Momentics IDE это интегрированная среда разработки для построения встроенных систем на базе ОС QNX Neutrino. Она является частью пакета разработки QNX Momentics development suite и предоставляется бесплатно для не коммерческого использования на сайте qnx.com. QNX Momentics IDE построена на базе IDE Eclipse и может быть запущена на различных платформах где может быть установлена виртуальная машина Java: Windows, Linux, Solaris и собственно на ОС QNX Neutrino
            После загрузки и установки дистрибутива IDE соответствующей вашей ОС на рабочем столе появится иконка. При первом запуске IDE в среде Windows вам предложат выбрать рабочую папку (workspace), где будут сохраняться все проекты. По умолчанию предлагается home_directory/ide4-workspace в Neutrino, Linux и Solaris, и C:/QNX/632/ ide4-workspace в Windows. Затем запуститься среда и отобразится окно приветствия. Для того что бы создать проект и приступить к написанию своего первого embedded-приложения нажмите на иконку Workbench а затем в меню File->New->C++ Project:

воскресенье, 3 июля 2011 г.

Комплексные числа

Мой класс описывающий базовые операции с комплексными числами.
Заголовочный файл mycomplex.h

#include <math.h>
namespace test
{
class Complex
{
public:
 // Конструктор по умолчанию
 Complex():itsRe(0),itsIm(0) { }
 // Конструктор с параметрами: действительная и мнимая часть
 Complex(double real, double imagine):itsRe(real),itsIm(imagine) { }
 // Конструктор копирования
 Complex(const Complex &);
 // Деструктор
 ~Complex() { itsRe = 0; itsIm = 0; }

 // Арифметические операции
 Complex operator+ (const Complex &);
 Complex operator- (const Complex &);
 Complex operator* (const Complex &);
 Complex operator/ (const Complex &);

 void operator+= (const Complex &);
 void operator-= (const Complex &);
 void operator*= (const Complex &);
 void operator/= (const Complex &);

 // Унарный оператор знака
 Complex operator- () const;

 // Операторы присваивания 
 Complex operator= (const Complex &);
 Complex operator= (const double &);

 // Функции доступа
 // Получить действительную часть 
 double GetReal() const { return itsRe; }
 // Получить мнимую часть
 double GetImagine() const { return itsIm; }
 
 // Модуль комплексного числа
 double GetAbs() const;
 // Аргумент комплексного числа
 double GetArg() const;
private:
 double itsRe;
 double itsIm;
};
}

mycomplex.cpp

#include "mycomplex.h"
namespace test{
Complex::Complex(const Complex & rhs)
{
 itsRe = rhs.itsRe;
 itsIm = rhs.itsIm;
}

Complex Complex::operator+ (const Complex & rhs)
{
 return Complex(itsRe + rhs.itsRe, itsIm + rhs.itsIm); 
}

Complex Complex::operator- (const Complex & rhs)
{
 return *this + (-rhs);
}

Complex Complex::operator* (const Complex & rhs)
{
 double re = (itsRe * rhs.itsRe) - (itsIm * rhs.itsIm);
 double im = (itsIm * rhs.itsRe) + (itsRe * rhs.itsIm);

 return Complex(re, im);
}

Complex Complex::operator/ (const Complex & rhs)
{
 double c = (rhs.itsRe * rhs.itsRe) + (rhs.itsIm * rhs.itsIm);
 double re = (itsRe * rhs.itsRe) + (itsIm * rhs.itsIm);
 double im = (itsIm * rhs.itsRe) - (itsRe * rhs.itsIm);

 return Complex(re/c, im/c); 
}

void Complex::operator+= (const Complex & rhs)
{
 *this = *this + rhs;
}

void Complex::operator-= (const Complex & rhs)
{
 *this = *this - rhs;
}

void Complex::operator*= (const Complex & rhs)
{
 *this = *this * rhs;
}

void Complex::operator/= (const Complex & rhs)
{
 *this = *this / rhs;
}

Complex Complex::operator- () const
{
 return Complex(-itsRe, -itsIm);
}

Complex Complex::operator= (const Complex & rhs)
{
 itsRe = rhs.itsRe;
 itsIm = rhs.itsIm;

 return *this;
}

Complex Complex::operator= (const double & rhs)
{
 itsRe = rhs;
 itsIm = 0;

 return *this;
}

double Complex::GetAbs() const
{
 return sqrt((itsRe * itsRe) + (itsIm * itsIm));
}

double Complex::GetArg() const
{
 if (itsRe > 0 || itsIm != 0)
  return 2 * atan( itsIm / (this->GetAbs() + itsRe) );
 else if (itsRe < 0 && itsIm == 0)
  return M_PI;
 
 return 0;
}
}

Пример использования. Для проверки корректности результатов проводится сравнение со встроенным в стандартную библиотеку классом Complex<T>.
#include "mycomplex.h"
#include <iostream>
#include <complex>


int main()
{
 test::Complex n2(2.0, 3.0);
 test::Complex n3 = n2+(-n2);
 std::cout << n2.GetReal() << ":" << n2.GetImagine() << "\n";
 std::cout << -n2.GetReal() << ":" << -n2.GetImagine() << "\n";
 std::cout << n3.GetReal() << ":" << n3.GetImagine() << "\n";

 std::cout << n2.GetArg() << ":" << n2.GetAbs() << "\n";

 std::complex<double> x(2., 3.);

 std::cout << std::arg(x) << ":" << std::abs(x) << "\n";

 return 0;
}

Многооконный режим редактирования файлов в Vim

С горизонтальной разбивкой:
vim -o file1 file2

C вертикальной разбивкой:
vim -O file1 file2

Просмотр отличий файлов:
vim -d file1 file2

ctrl+w - переход на следующее окно
ctrl+w, n - создать новое окно
ctrl+w, + - увеличить размер окно

Стек и функции

Ниже перечислены действия, происходящие с программой, выполняемой под управлением DOS, при переходе к телу функции:
  1. Увеличивается адрес, содержащийся в указателе команды, чтобы указывать на инструкцию следующую после вызова функции. Затем этот адрес помещается в стек и будет служить адресом возврата по завершении выполнения функции.
  2. В стеке резервируется место для возвращаемого функцией значения объявленного вами типа. Если в системе с двухбайтовыми целыми для возвращаемого значения объявлен тип int, то к стеку добавляется еще два байта, но в эти байты ничего пока не помещается. 
  3. В указатель команды загружается адрес вызванной функции, который хранится в отдельной области памяти, отведенной специально для этих целей. Поэтому следующей выполняемой командой будет первый оператор вызванной функции.
  4. Текущая вершина стека помечается и содержится в специальном указателе, именуемом указателем стека. Все, что добавляется в стек с этого момента и до тех пор, пока функция не завершится, рассматривается как локальные данные этой функции. 
  5. В стек помещаются все аргументы, передаваемые функции.
  6. Выполняется команда, адрес которой находится в данный момент в указателе команды, т.е. первая строка кода функции.
  7. По мере определения в стеке размещаются локальные переменные и функции.
Когда функция завершается, возвращаемое значение помещается в область стека, зарезервированную на этапе 2. Затем из стека удаляется все содержимое вплоть до указателя стека, благодаря чему стек очищается от локальных переменных и аргументов переданных функции.
Затем из стека извлекается значение возврата функции, которое присваивается переменной, вызвавшей функцию, и адрес команды, сохраненный в стеке на этапе 1, который присваивается указателю команд. Таким образом, программа продолжает свою работу со следующей строки после обращения к функции, владея уже значением, возвращенным из функции.