Сокращения и условные обозначения. Переменные и условный оператор

Условную переменную можно использовать для реализации отношений синхронизации, о которых упоминалось выше: старт-старт (CC), финиш-старт (ФС), старт-финиш (СФ) и финиш-финиш (ФФ). Эти отношения могут существовать между потоками одного или различных процессов. В листингах 5.4 и 5.5 представлены примеры реализации ФС- и ФФ-отношений синхронизации. В каждом примере определено два мьютекса. Один мьютекс используется для синхронизации доступа к общим данным, а другой - для синхронизации выполнения кода.

// Листинг 5.4. ФС-отношения синхронизации между

// двумя потоками

pthread_t ThreadA,ThreadB;

pthread_cond_t Event;

void * worker1 (void *X) {

for(int Count = l;Count

pthread_mutex_lock(&Mutex);

pthread_mutex_unlock(&Mutex);

if(Number == 50){

pthread_cond_signal(&Event);

void * worker2 (void *X) {

pthread_mutex_lock(&EventMutex);

pthread_cond_wait(&Event,&EventMutex);

for(int Count = 1;Count

pthread_mutex_lock(&Mutex);

Number = Number + 20;

pthread_mutex_unlock(&Mutex);

cout « «Выполнение функции worker2 завершено.» « endl; return(0);

int main (int argc, char *argv) {

pthread_mutex_init(&Mutex,NULL);

pthread_mutex_init(&EventMutex,NULL);

pthread_cond_init(&Event, NULL);

pthread_create(&ThreadA, NULL, workerl, NULL);

pthread_create(&ThreadB, NULL, worker2 , NULL);

В листинге 5.4 показан пример реализации ФС-отношений синхронизации. Поток ThreadA не может завершиться до тех пор, пока не стартует поток ThreadB. Если значение переменной Number станет равным 50, поток ThreadA сигнализирует о этом потоку ThreadB. Теперь он может продолжать выполнение до самого конца Поток ThreadB не может начать выполнение до тех пор, пока не получит сигнал от потока ThreadA. Поток ThreadB использует объект EventMutex вместе с условной переменной Event. Объект Mutex используется для синхронизации доступа для записи значения разделяемой переменной Number. Для синхронизации различных событий и доступа к критическим разделам задача может использовать несколько мьютексов.

Пример реализации ФФ-отношений синхронизации показан в листинге 5.5.

// Листинг 5.5. ФФ-отношения синхронизации между // двумя потоками

pthread_t ThreadA, ThreadB ;

pthread_mutex_t Mutex, EventMutex;

pthread_cond_t Event;

void *workerl(void *X) {

for(int Count = l;Count

pthread_mu tex_l ock (&Mutex);

pthread_mutex_unlосk(&Mutex);

cout « «workerl: число равно "

pthread_mutex_lock(&EventMutex) ,-

cout « «Функция workerl в состоянии ожидания. " « endl;

pthread_cond_wait (&Event, &EventMutex) ;

pthread_mutex_unlock(&EventMutex);

void *worker2 (void *X) {

for(int Count = l;Count

pthread_mutex_lock(&Mutex) ;

Number = Number * 2 ;

pthread_mutex_unlock(&Mutex) ;

cout « «worker2: число равно " « Number « endl;

pthread_cond_signal (&Event) ;

cout « «Функция worker2 послала сигнал " « endl; return(0);

int main(int argc, char *argv) {

pthread_mutex_init (&Mutex,NULL) ;

pthread_mutex_init (&EventMutex,NULL) ;

pthread_cond_init (&Event, NULL) ;

pthread_create(&ThreadA, NULL,workerl, NULL);

pthread_create (&ThreadB, NULL, worker2, NULL) ;

В листинге 5.5 поток ThreadA не может завершиться до тех пор, пока не завершится поток ThreadB. Поток ThreadA должен выполнить цикл 10 раз, а ThreadB - 100. Поток ThreadA завершит выполнение своих итераций раньше ThreadB, но будет ожидать до тех пор, пока поток ThreadB не просигналит о своем завершении.

CC- и СФ-отношения синхронизации невозможно реализовать подобным образом. Эти методы используются для синхронизации пор я дка выполнени я процессов.

ТАУ – теория автоматического управления

ТС – техническая система

ОУ- объект управления

УУ- управляющее устройство

СУ – система управления

ИО – исполнительный орган

ИУ – исполнительное устройство

Д – датчик

ОС – обратная связь

ПК – передаточный коэффициент

ПФ – передаточная функция

АФЧХ – амплитудно-фазовая частотная характеристика

АЧХ – амплитудно-частотная характеристика

ЛАЧХ – логарифмическая амплитудно-частотная характеристика

ФЧХ - фазо-частотная характеристика

2. Условные обозначения основных переменных и функций

x (t ) – входной сигнал элемента СУ, выходной сигнал ОУ и СУ (управляемая величина)

y (t ) – выходной сигнал элемента СУ, входной сигнал ОУ (управляющее воздействие)

x з (t ) – задающее воздействие СУ

z (t ) – возмущающее воздействие на СУ

(t ) – сигнал ошибки (рассогласования) в СУ

1(t ) – единичное ступенчатое воздействие

(t ) – единичное импульсное воздействие

x m ,y m – амплитудные значения сигналовx (t ) иy (t )

p – оператор Лапласа, оператор дифференцирования

 - круговая частота, оператор преобразования Фурье

X (p ) – изображение непрерывного сигналаx (t ) по Лапласу

X (j ) – изображение непрерывного сигналаx (t ) по Фурье

k – ПК звена (или соединения звеньев)

W (p ) – ПФ звена (или соединения звеньев)

W (j ) – АФЧХ звена (или соединения звеньев)

А () – АЧХ звена (или соединения звеньев)

() – ФЧХ звена (или соединения звеньев)

Ф(р ) – ПФ замкнутой СУ

h (t ) – переходная функция (характеристика) звена или СУ

w (t ) – импульсная (весовая) функция (характеристика) звена или СУ

ВВЕДЕНИЕ

Теория автоматического управления (ТАУ) – научная дисциплина, предметом изучения которой являются информационные процессы, протекающие в системах управления техническими и технологическими объектами. ТАУ выявляет общие закономерности функционирования автоматических систем различной физической природы и на основе этих закономерностей разрабатывает принципы построения высококачественных систем управления.

При изучении процессов управления в ТАУ абстрагируются от физических и конструктивных особенностей систем и вместо реальных систем рассматривают их адекватные математические модели. Чем точнее (полнее) математическая модель соответствует физическим процессам, протекающим в реальной системе, тем совершеннее будет проектируемая система управления.

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

Метод математического моделирования , объединяющий самые разнообразные способы и приёмы описания и представления физических объектов и явлений, можно условно, схематично представить с помощью наиболее часто используемого приёма – графическим изображением простого объекта, имеющего один входной сигнал x (t ) и один выходной сигнал y (t ), в виде прямоугольника (рис. В. 1,а ). Символ А внутри прямоугольника означает некоторый математический оператор (функцию, интеграл и т. п.), который связывает входной и выходной сигналы, меняющиеся во времени.

Рис. В.1. Схематичное представление математических методов, используемых в ТАУ

Теория обыкновенных дифференциальных уравнений , акцентирующая своё внимание на физические аспекты и приложения получаемых решений, служит главной методологической основой ТАУ, а сами обыкновенные дифференциальные уравнения – наиболее общей и полной формой математического описания элементов и систем управления. Дифференциальные уравнения связывают меняющиеся во времени входные и выходные переменные и их производные. В простейшем случае дифференциальное уравнение имеет вид

dy (t )/dt =f [x (t ),y (t )]. (В.1)

Метод операционного исчисления , в основе которого лежит преобразование Лапласа

(В.2)

позволяет алгебраизировть дифференциальные уравнения – перейти к так называемым операторным уравнениям, связывающим изображения X (p ) и Y (p ) входного и выходного сигналов через передаточную функцию W (p ) (рис. В. 1,б )

W (p )=Y (p )/X (p ). (В.3)

Метод гармонического анализа основан на известном из курса математики преобразовании Фурье, имеющем вид

(В.4)

С помощью преобразования Фурье (В. 4) находят изображения X (j ) и Y (j ) входного и выходного сигналов x (t ) и y (t ), характеризующие частотные спектры этих сигналов. Изображения сигналов по Фурье связаны (рис.В. 1,в ) частотной передаточной функцией

W (j )=Y(j )/X(j ). (В.5)

Все четыре метода, кратко представленные выше, образуют математический аппарат ТАУ. На его базе разработан комплекс «собственных» методов ТАУ, излагаемых в настоящем курсе.

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

Техническая кибернетика наряду с биологической и социоэкономической – составная часть кибернетики, которую её родоначальник, американский математик Н. Винер, в 1948 году определил как науку об управлении и связи в технических системах и живых организмах.

Первые промышленные регуляторы появились в период 1765-1804 гг. (И. Ползунов, Дж. Уатт, Ж. Жаккар).

Первые теоретические исследования регуляторов появились в период 1868-1893 гг. (Дж. Максвелл, И. Вышнеградский, А. Стодола). Российский учёный и инженер И. А. Вышнеградский выполнил ряд научных исследований, в которых паровая машина и её регулятор впервые были проанализированы математическими методами как единая динамическая система. В становлении российской школы ТАУ большую роль сыграли работы А. А. Андронова, В. С. Кулебакина, И. Н. Вознесенского, Б. В. Булгакова, А. А. Фельдбаума, Б. Н. Петрова, Н. Н. Красовского, А. А. Воронова, Я. З. Цыпкина, В. С. Пугачёва, …

Развитие современной теории управления из так называемой «классической» теории регулирования, основанной на четырёх вышеупомянутых основных методах исследования ТАУ, и формирование её новейших методов схематично проиллюстрированы на рис. В. 2.

Рис. В.2. Развитие содержания и методологии теории управления

В настоящее время ТАУ наряду с новейшими разделами общей теории управления (исследование операций, системотехника, теория игр, теория массового обслуживания) играет важнейшую роль в совершенствовании и автоматизации управления технологическими процессами и производствами.

Условные переменные

Условная переменная (condvar - сокращение от condition variable) используется для блокировки потока по какому-либо условию во время выполнения критической секции кода. Условие может быть сколь угодно сложным и не зависит от условной переменной. Однако условная переменная всегда должна использоваться совместно с мьютексом для проверки условия.

Условные переменные поддерживают следующие функции:

· ожидание условной переменной (wait) (pthread_cond_wait() );

· единичная разблокировка потока (signal) (pthread_cond_signal() )

· множественная разблокировка потока (broadcast) (pthread_cond_broadcast() ),

Приведем пример типичного использования условной переменной:

pthread_mutex_lock (&m) ;-…

while (!arbitrary condition) {

pthread_cond_wait(&cv, &m);

pthread_mutex_unlock (&m) ;

В этом примере захват мьютекса происходит до проверки условия. Таким образом, проверяемое условие применяется только к текущему потоку. Пока данное условие является истинным, эта секция кода блокируется на вызове ожидания до тех пор, пока какой-либо другой поток не выполнит операцию единичной или множественной разблокировки потока по условной переменной.

Цикл while в приведенном примере требуется по двум причинам. Во-первых, стандарты posix не гарантируют отсутствие ложных пробуждений (например, в многопроцессорных системах). Во-вторых, если другой поток изменяет условие, необходимо заново выполнить его проверку, чтобы убедиться, что изменение соответствует принятым критериям. При блокировании ожидающего потока связанный с условной переменной мутекс атомарно освобождается функцией pthread_cond_wait() для того, чтобы другой поток мог войти в критическую секцию программного кода.

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

Другой вид операции ожидания условной переменной (pthread__cond_timedwair() ) позволяет установить таймаут. По окончании этого периода ожидающий поток может быть разблокирован.

Барьеры

Барьер - это механизм синхронизации, который позволяет скоординировать работу нескольких взаимодействующих потоков таким образом, чтобы каждый из них остановился в заданной точке в ожидании остальных потоков, прежде чем продолжить свою работу.

В отличие от функции pthreadjoin() , при которой поток ожидает завершения другого потока, барьер заставляет потоки встретиться в определенной точке. После того как заданное количество потоков достигает установленного барьера, все эти потоки разблокируются и продолжат свою работу. Барьер создается с помощью функции pthread_barrier_init():

#include

pthread_barrier_init (pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count);

В результате выполнения этого кода создается барьер по заданному адресу (указатель на барьер находится в аргументе barrier) и с атрибутами, установ­ленными аргументом attr. Аргумент count задает количество потоков, кото­рые должны вызвать функцию pthread_barrier_wait().

После создания барьера каждый поток вызывает функцию pthread_barrier_wait (), тем самым сообщая о завершения этого действия:

#include

int pthread_barrier_wait (pthread_barrier_t "barrier};

Когда поток вызывает функцию pthread_barrier_wait(), он блокируется до тех пор, пока то число потоков, которое было задано функцией pthread_barrier_init() , не вызовет функцию pthread_jbarrier_wait() и, соответст­венно, не заблокируется. После того как заданное количество потоков вы­зовет функцию pthread_barrier_wait() , все они разблокируются одновременно .

#include

#include

#include

#include

pthread_barrier_t barrier; // объект синхронизации типа "барьер"

main () // игнорировать аргументы

time_t now;// создать барьер со значением счетчика 3

pthread_barrier_init (&barrier, NULL, 3); // стартовать два потока - threadl и thread2

pthread_create (NOLL, NOLL, threadl, NULL); // потоки threadl и thread2 выполняются

pthread_create (NDLL, NDLL, thread2, NDLL);// ожидание завершения

printf ("main() waiting for barrier at %s", ctime (&now));

pthread_barrier_wait (&barrier);// после этого момента все три потока завершены

printf ("barrier in mainO done at %s", ctime (&now));

threadl (void *not used)

time (&now); // выполнение вычислений

printf ("threadl starting at %s", ctime (&now));// пауза

pthread_barrier_wait (&barrier) ;// после этого момента все три потока завершены

printf ("barrier in threadl{) done at %s", ctime (&now)) ;

thread2 (void *not__used)

time (&now) ; // выполнение вычислений

printf ("thread2 starting at %s", ctime (&now));// пауза

pthread_barrier_wait (&barrier) ;

// после этого момента все три потока завершены

printf {"barrier in thread2() done at %s", ctime (&now));

В примере из листинга основной поток создает барьер, после запуска которого начинается подсчет количества потоков, заблокированных на барьере для синхронизации. В данном случае количество синхронизируемых потоков задается равным 3: поток main(), поток thread1() и поток thread2().

Запускаются потоки thread1() и thread2(). Для наглядности в потоке задается пауза, чтобы имитировать процесс вычислений. Для выполнения синхрони­зации основной поток блокируется на барьере и ожидает разблокировки, которая произойдет после того, как остальные два потока не присоединятся к нему на этом барьере.



Ждущие блокировки

Ждущие блокировки (sleepon locks) работают аналогично условным пере­менным, за исключением некоторых деталей. Как и условные переменные, ждущие блокировки (pthread_sleepon_lock() ) могут использоваться для бло­кировки потока до тех пор, пока условие не станет истинным (аналогично изменению значения ячейки памяти). Но в отличие от условных перемен­ных (которые должны существовать для каждого проверяемого условия), ждущие блокировки применяются к одному мm.тексу и динамически созда­ваемой условной переменной независимо от количества проверяемых усло­вий. Максимальное число условных переменных в конечном итоге равно максимальному числу блокированных потоков.

Условные переменные

Условная переменная представляет собой семафор, используемый для сигнализации о событии, которое произошло. Сигнала о том, что произошло некоторое событие, может ожидать один или несколько процессов (или потоков) от других процессов или потоков. Следует понимать различие между условными переменными и рассмотренными выше мьютексными семафорами. Назначение мьютексного семафора и блокировок чтения-записи - синхронизировать доступ к данным, в то время как условные переменные обычно используются для синхронизации последовательности операций. По этому поводу в своей книге UNIX Network Programming прекрасно высказался Ричард Стивенс (W. Richard Stevens): « Мьютексы нужно использовать для блокирования, а не для ожидания ».

В листинге 4.6 поток-«потребитель» содержал цикл:

15 while(TextFiles.empty())

Поток-«потребитель» выполнял итерации цикла до тех пор, пока в очереди TextFiles были элементы. Этот цикл можно заменить условной пере м енной. Поток-«изготовитель» сигналом уведомляет потребителя о том, что в очередь помещены элементы. Поток-«потребитель» может ожидать до тех пор, пока не получит сигнал, а затем перейдет к обработке очереди.

Условная переменная имеет тип pthread_cond_t. Ниже перечислены типы операций, которые может она выполнять:

Инициализация;

Разрушение;

Ожидание;

Ожидание с ограничением по времени;

Адресная сигнализация;

Всеобщая сигнализация;

Операции инициализации и разрушения выполняются условными переменными подобно аналогичным операциям других мьютексов. Функции класса pthread_cond_t, которые реализуют эти операции, перечислены в табл. 5.7.

Таблица 5.7. Функции класса pthread_cond_t, которые реализуют операции условных переменных

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

pthread_mutex_lock(&Mutex) ;

pthread_cond_wait(&EventMutex, &Mutex);

pthread_mutex_unlock(&Mutex) ;

Итак, некоторая задача делает попытку заблокировать мьютекс. Если мьютекс уже заблокирован, то эта задача блокируется. После разблокирования задача освободит мьютекс Mutex и при этом будет ожидать сигнала для условной переменной EventMutex . Если мьютекс не заблокирован, задача будет ожидать сигнала неограниченно долго. При ожидании с ограничением по времени задача будет ожидать сигнала в течение заданного интервала времени. Если это время истечет до получения задачей сигнала, функция возвратит код ошибки. Затем задача вновь затребует мьютекс.

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

Условная переменная также имеет атрибутный объект, функции которого перечислены в табл. 5.8.

Таблица 5.8. Функции доступа к атрибутному объекту для условной переменной типа pthread_cond_t


Int pthread_condattr_init (pthread_condattr_t * attr) Инициализирует атрибутный объект условной переменной, заданный параметром attr, значениями, действующими по умолчанию для всех атрибутов, определенных реализацией;

Int pthread_condattr_destroy (pthread_condattr_t * attr) ; Разрушает атрибутный объект условной переменной, заданный параметром attr. Этот объект можно инициализировать повторно, вы-звав функцию pthread_condattr_init ()

Int pthread_condattr_setpshared (pthread_condattr_t * attr,int pshared);

Int pthread_condattr_getpshared (const pthread_condattr_t * restrict attr, int *restrict pshared); Устанавливает или возвращает атрибут process-shared атрибутного объекта условной переменной, заданного параметром attr. Параметр pshared может содержать следующие значения:

PTHREAD_PROCESS_SHARED (разрешает блокировку чтения-записи, разделяемую любыми потоками, которые имеют доступ к памяти, выделенной для этой условной переменной, даже если потоки принадлежат различным процессам);

PTHREAD_PROCESS_PRIVATE (Условная Переменная разделяется между потоками одного процесса)

Int pthread_condattr_setclock (pthread_condattr_t * attr, clockid_t clock_id);

Int pthread_condattr_getclock (const pthread_condattr_t * restrict attr, clockid_t * restrict clock_id); Устанавливает или возвращает атрибут clock атрибутного объекта условной переменной, заданного параметром attr . Атрибут clock представляет собой идентификатор часов, используемых для измерения лимита времени в функции pthread_cond_timedwait (). По умолчанию для атрибута clock используется идентификатор системных часов

Объявление

Переменная — это величина, имеющая имя и значение. Переменные объявляются с помощью слова var: var x = 12, y; Здесь введено две переменных с именами x и y , в переменную x записано значение 12 , а переменная y не определена, то есть команда трассировки trace (y); выдаст результат undefined (значение не определено). Такой же результат выдает и команда trace (z); потому что переменная z вообще неизвестна. Для того, чтобы отличить существующую переменную от неизвестной, можно записать в нее специальное нулевое значение null: var y = null ;

Если тип переменной явно не указан, она может принимать любые значения. Например:

var x = 1; // число x = "Ку-ку!" ; // строка x = false ; // логическое значение

Однако при объявлении лучше явно указывать тип переменной. Это позволяет обнаруживать многие ошибки еще до выполнения программы. Существует три простых типа:

  • Number — число;
  • String — строка;
  • Boolean — логическое значение.
Тип переменной указывается после ее имени через двоеточие var x:Number = 0, y:String = "qq" , b:Boolean = false ; В переменные типа String можно записывать символьные строки, заключенные в кавычки или одиночные апострофы: var s1:String = "qq1", s2:String = "qq2"; Логические переменные принимают только два значения: true (истина) и false (ложь): var b:Boоlean = false ; b = true ; b = (a В последнем случае значение переменной b будет равно true , если условие справа от знака равенства верно.

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

var x:Number = 1; x = "Ку-ку!" ;

Видимость переменных

Различают три вида переменных: Глобальные переменные объявляются с помощью описателя _global: _global .x = 12; Обратите внимание, что слово var здесь использовать не нужно, такие переменные рассматриваются как свойства объекта _global . К переменной x , которая объявлена выше, можно обращаться из любой функции и из кода любого клипа просто по имени.

Если в области видимости есть несколько переменных с одним и тем же именем, сначала ищется локальная переменная, затем — переменная текущего клипа, и только потом — глобальная переменная.

Переменные других клипов «не видны», для обращения к ним нужно указывать явно клип-родитель:

Mc.x = 1; _root .x = 12; _parent .x = 123;

Присваивание

Для присваивания переменной нового значения используется знак = . Слева от него пишут имя переменной, а справа — выражение: a = 4*(c + 2) + 3 / (r - 4*w) + d % 3; Знак * обозначает умножение, знак / — деление, а % — взятие остатка от деления.

В выражении арифметические операции выполняются в следующем порядке:

  • действия в скобках;
  • умножение, деление и взятие остатка (слева направо);
  • сложение и вычитание (слева направо).
Этот порядок называется приоритетом (старшинством) арифметических операций.

Символьные строки можно «сцеплять» с помощью оператора + :

No = 20; s = "Вася " + "пошёл гулять." ; qq = "Объект" + no; Если в выражении участвуют разнотипные данные, происходит автоматическое преобразование к одному типу. Так в последней строке в переменную qq записывается строка Объект20 .

Очень часто в программах используют операторы ++ (инкремент , увеличение переменной на 1, и -- (декремент , уменьшение переменной на 1). Операторы

I ++; k --; означают то же самое, что i = i + 1; k = k - 1; Существует также сокращенная запись арифметических операций: a += 20; b -= c - d; c *= a + b; d /= 2*c; f %= 12; Этот код можно заменить на такие операторы в «нормальной» форме: a = a + 20; b = b - (c - d); c = c * (a + b); d = d / (2 * c); f = f % 12

Объекты

Объект — это нечто, имеющее свойства и методы. В среде Flash существуют встроенные объекты (например, Array , MovieClip , Key). Кроме того, можно строить свои объекты: var car = new Object (); car.v = 10; car.year = 1998; В среде Flash можно использовать объектно-ориентированное программирование, то есть создавать свои классы объектов, наделять их свойствами и методами (см. Тему 13).

Главная особенность объектов — это так называемая ссылочная адресация. То есть, при объявлении

var obj = new Object (); переменная obj хранит не сам объект, а только его адрес (ссылку на объект). Поэтому оператор присваивания obj2 = obj; не создает в памяти новый объект, который является копией объекта obj , а просто копирует адрес первого объекта в переменную obj2 . После этого obj и obj2 указывают на один объект. Если мы хотим действительно построить копию объекта, адрес которого хранится в obj , можно сделать так: var obj2 = new Object (); for (prop in obj) obj2 = obj; Здесь в цикле перебираются все свойства первого объекта и копируются во второй. Переменная prop (символьная строка) — это название очередного свойства. Запись obj означает «свойство объекта obj , название которого хранится в prop ».