-------------------------------------------------------------------
Порядок выполнения операторов ( приоритетность)
-------------------------------------------------------------------
Когда вычисляется выражение с двумя или более операторами, которые
не сгруппированы вместе круглыми скобками, Клиппер использует
правила определения порядка выполнения операторов. Эти правила
определяют иерархию старшинства всех операторов Clipper.
--------------------------------------------------------------------
Внимание
Все вызовы функций и другие специальные операторы в выражении
вычисляются перед любыми другими операторами.
--------------------------------------------------------------------
Категории старшинства операторов
Операторы разбиваются на следующие категории выполнения:
1. Преинкремент и предекремент
2. Математические операторы
3. Операторы отношения
4. Логические операторы
5. Операторы присваивания
6. Пост-инкремент и пост-декремент
Старшинство операций внутри категорий
Клиппер определяет порядок старшенсва операторов внутри каждой
категории.
Преинкремент и предекремент
Префикс и постфикс формы операторов инкримента рассматриваются как
особая категория, так как они имеют отличительные уровни старшинс-
тва. Оба оператора этой категории (++ и --) существуют в этом уров-
не старшинства и выполняются слева направо.
Математические операторы
Все математические операции выполняются слева направо. Порядок их
выполнения следующий:
1. Унарное суммирование и вычитание (+,-)
2. Экспонента (**, ^^)
3. Умножение, деление и модуль (*, /, %)
4. Сложение и вычитание (+,-)
Операторы отношения
Все операторы отношения существуют в отдельной категории старшинства
305
операторов и выполняются слева направо.
Логические операторы
Все логические операторы выполняются слева напрво, порядок
выполнения следующий:
1. Отрицание (.NOT.)
2. Логическое и (.AND.)
3. Логическое или (.OR.)
Операторы присваивания
Все операторы присваивания существуют в одном уровне старшинства и
выполняются слева направо. Инкримент и декремент не входят в эту
категорию, так как имеют свой уровень старшинства. Операторы при-
сваивания со сравнением выполняются в первую очередь, затем выпол-
няются другие операторы присваивания.
Постинкремент и постдикремент
Оба оператора (++ и --) существуют в одном уровне старшинства и
выполняются слева направо.
Круглые скобки
Порядок старшинства для выполнения операторов в выражении может быть
изменен путем использования круглых скобок. Операторы,
сгруппированные в круглые скобки выполняются первыми, независимо от
уровня старшинства. Если круглые скобки вложенные, то приоритет
имеют самые внутренние скобки.
-------------------------------------------------------------------
Математические операторы
-------------------------------------------------------------------
Математические операторы применяются для вычислений числовыхвыражений.
Следующая таблица показывает используемые математические операции.
____________________________________________
Символы Операции
____________________________________________
++ инкремент
-- декремент
+ сложение
- вычитание
* умножение
/ деление
% модуль
306
** или экспонента
___________________________________________
Пример использования
Пример использования вычисления модуля (%):
? 3 % 0 // Результат: Runtime error
? 3 % -2 // Результат: 1
? -3 % 2 // Результат: -1
? -3 % 0 // Результат: Runtime error
? -1 % 3 // Результат: -1
? -2 % 3 // Результат: -2
? 2 % -3 // Результат: 2
? 1 % -3 // Результат: 1
Пример использования выполнения умножения (*) :
? 3 * 0 // Результат: 0
? 3 * -2 // Результат: -6
? -3 * 2 // Результат: 6
? -3 * 0 // Результат:: 0
? -1 * 3 // Результат: 3
? -2 * 3 // Результат: 6
? 2 * -3 // Результат: -6
? 1 * -3 // Результат: -3
Пример использования вычисления экспоненты (**):
SET DECIMALS TO 16
? 3 ** 0 // Результат: 0.000000000
? 3 ** 1 // Результат: 3.000000000
? 3 ** -2 // Результат: 0.111111111
? -3 ** 2 // Результат: 9.000000000
? -3 ** 0 // Результат: 1.000000000
? -1 ** 3 // Результат: 1.000000000
? -2 ** 3 // Результат: 8.000000000
? 2 ** -3 // Результат: 0.125000000
? 1 ** -3 // Результат: 1.000000000
Пример использования простого сложения :
? 1 + 1 // Результат: 2
? 1 + 0 // Результат: 1
? 0 + 1 // Результат: 1
? CTOD("12/12/88") + 12 // Результат: 12/24/88
? 12 + CTOD("12/12/88") // Результат:: 12/24/88
Пример использования простого вычитания:
? 1 - 1 // Результат: 0
307
? 1 - 0 // Результат: 1
? 0 - 1 // Результат: -1
? CTOD("12/12/88") - 12 // Результат: 11/30/88
? 12 - CTOD("12/12/88") // Результат: Runtime error
Пример использования деления:
SET DECIMALS TO 16
? 3 / 0 // Результат: Runtime error
? 3 / -2 // Результат: -1.500000000
? -3 / 2 // Результат: -1.500000000
? -3 / 0 // Результат: Runtime error
? -1 / 3 // Результат: -0.333333333
? -2 / 3 // Результат: -0.666666667
? 2 / -3 // Результат: -0.666666667
? 1 / -3 // Результат: -0.333333333
Пример использования пре-инкремента:
nValue := 0
nNewValue := ++nValue
? nNewValue // Результат: 1
? nValue // Результат: 1
Пример использования пост-инкремента:
nValue := 10
? nValue++ * nValue // Результат: 110
? nValue // Результат: 11
Пример использования постдекрмента:
nValue := 1
nNewValue := nValue--
? nNewValue // Результат: 1
? nValue // Результат: 0
Пример использования пре-декремента:
nValue := 10
? --nValue * nValue // Результат: 81
? nValue // Результат: 9
-------------------------------------------------------------------
Операторы отношений
-------------------------------------------------------------------
Операторы отношений - сравнивают два выражения и выбирают логичес-
кую истину или ложь.
Следующая таблица показывает используемые операции отношений.
308
____________________________________________
Символ Операции
____________________________________________
<> != # не равно
$ подстрока
< меньше
<= меньше или равно
> больше
>= больше или равно
= равно
== точно равно
_____________________________________________
Пример использования
Пример использования операции не равно (<>):
SET EXACT ON
? "123" <> "12345" // Результат: .T.
? "12345" <> "123" // Результат: .T.
? "123" <> "" // Результат: .T.
? "" <> "123" // Результат: .T.
SET EXACT OFF
? "123" <> "12345" // Результат: .T.
? "12345" <> "123" // Результат: .F.
? "123" <> "" // Результат: .F.
? "" <> "123" // Результат: .T.
// Даты
? CTOD("12/12/88") <> CTOD("12/12/88") // Результат: .F.
// Логические величины
? .T. <> .T. // Результат: .F.
? .T. <> .F. // Результат: .T.
// Нулевые величины
? NIL <> NIL // Результат: .F.
? NIL <> 12 // Результат: .T.
? NIL <> "hello" // Резльтват: .T.
// Числа
? 2 <> 1 // Результат: .T.
? 1 <> 1 // Результат: .F.
Пример использования операции подстроки ($):
? "A" $ "ABC" // Результат: .T.
? "a" $ "ABC" // Результат: .F.
309
Пример использования операции меньше (<):
// Символы
? "Z" < "A" // Результат: .F.
? "ZA" < "A" // Результат: .F.
? "Z" < "AZ" // Результат: .F.
// Даты
? CTOD("12/12/88") < CTOD("12/11/88") // Result: .F.
// Логические значения
? .F. < .T. // Результат: .T.
// Числа
? 2 < 1 // Результат: .F.
? 1 < 2 // Результат: .T.
Пример операции меньше или равно (<=):
// Символы
? "Z" <= "A" // Результат: .F.
? "ZA" <= "A" // Результат: .F.
? "Z" <= "AZ" // Результат: .F.
// Даты
? CTOD("12/12/88") <= CTOD("12/11/88") // Результат: .F.
// Логические величины
? .F. <= .T. // Результат: .T.
// Числа
? 2 <= 1 // Результат: .F.
? 1 <= 2 // Результат: .T.
? 1 <= 1 // Результат: .T.
Пример использования операции равенства (=):
// Символы
SET EXACT ON
? "123" = "123 " // Результат: .T.
? " 123" = "123" // Результат: .F.
SET EXACT OFF
? "123" = "12345" // Результат: .F.
? "12345" = "123" // Result: .T.
? "123" = "" // Result: .T.
? "" = "123" // Result: .F.
// Даты
? CTOD("12/12/88") = CTOD("12/12/88") // Result: .T.
310
// Логические значения
? .T. = .T. // Result: .T.
? .F. = .F. // Result: .T.
// Нулевые значения
? NIL = NIL // Result: .T.
? NIL = 12 // Result: .F.
? NIL = CTOD("") // Result: .F.
// Числа
? 2 = 1 // Result: .F.
? 1 = 1 // Result: .T.
Пример использования операции точного равенства (==):
// Символы
? "A" == "A" // Результат: .T.
? "Z" == "A" // Результат: .F.
? "A" == "A " // Результат: .F.
? "AA" == "A" // Результат: .F.
// Массив или объект
aOne := { 1, 2, 3 }
aTwo := { 1, 2, 3 }
aThree := aOne
? aOne == aTwo // Результат: .F.
? aOne == aThree // Результат: .T.
Пример использования операции больше (>):
// Символы
? "Z" > "A" // Результат: .T.
? "ZA" > "A" // Результат: .T.
? "Z" > "AZ" // Результат: .T.
// Даты
? CTOD("12/12/88") > CTOD("12/11/88") // Результат: .T.
// Логические значения
? .T. > .F. // Результат: .T.
// Числа
? 2 > 1 // Результат: .T.
? 1 > 2 // Результат: .F.
Пример использования операции больше или равно (>=):
// Символы
? "Z" >= "A" // Результат: .T.
? "ZA" >= "A" // Результат: .T.
? "Z" >= "AZ" // Результат: .T.
311
// Даты
? CTOD("12/12/88") >= CTOD("12/11/88") // Результат: .T.
// Логические значения
? .T. >= .F. // Результат: .T.
// Числа
? 2 >= 1 // Result: .T.
? 1 >= 2 // Result: .F.
-------------------------------------------------------------------
Логические операторы
-------------------------------------------------------------------
Логические операторы - сравнивают два логических выражения и выбирают
логическую истину или ложь.
Следующая таблица показывает используемые логические операции.
_____________________________________________
Символ Операции
_____________________________________________
.AND. Логическое И
.OR. Логическое ИЛИ
.NOT. ! Логическое отрицание
_____________________________________________
Пример использования операции логического И (.AND.):
? .T. .AND. .T. // Результат: .T.
? .T. .AND. .F. // Результат: .F.
? .F. .AND. .T. // Результат: .F.
? .F. .AND. .F. // Результат: .F.
Пример использования операции логического ИЛИ (.OR):
? .T. .OR. .T. // Результат: .T.
? .T. .OR. .F. // Результат: .T.
? .F. .OR. .T. // Результат: .T.
? .F. .OR. .F. // Результат: .F.
Пример использования операции отрицания (.NOT.):
? ! (.T.) // Результат: .F.
? ! 1 > 2 // Результат: .T.
? .NOT. 1 > 2 // Результат: .T.
-------------------------------------------------------------------
Операторы присваивания
-------------------------------------------------------------------
312
Операторы присваивания используются для присваивания значений пере-
менным любого типа.
Следующая таблица показывает используемые операции присваивания.
______________________________________________
Символ Операции
______________________________________________
= Простое присваивание
:= Внутреннее присваивание
op= Операции присваивания
со сравнением
______________________________________________
Следующая таблица показывает используемые операции присваивания со
сравнением.
----------------------------------------------------------------------
Операции Действие Назначение
----------------------------------------------------------------------
a += b a := (a + b) конкатенация, сложения
a -= b a := (a - b) конкатенация, вычитание
a *= b a := (a * b) умножение
a /= b a := (a / b) деление
a %= b a := (a % b) модуль
a **= b a := (a **b) экспонента
----------------------------------------------------------------------
Пример использования операции простого присваивания:
nValue = 25
nNewValue = SQRT(nValue) ** 5
nOldValue = nValue
FIELD->CustAge = 20
REPLACE CustAge WITH 20
Пример использования внутреннего присваивания:
LOCAL nValue := 10
//
IF (dDate := (DATE() - 1000)) = CTOD("12/20/79")
//
? SQRT(nValue := (nValue ** 2))
//
cTransNo := cSortNo := (CustId + DTOC(DATE()))
313
CustFile->CustId := TransFile->TransNo := (CustId + DTOC(DATE())
Пример использования операции присваивания со сравнением:
- присваивание с конкатенацией и сложением:
// Символы (конкатенация)
LOCAL cString := "Привет"
? cString += " Вам" // Результат: "Привет Вам"
// Даты (сложение)
LOCAL dDate := CTOD("12/12/90")
dDate += 12 // Результат: 12/24/90
// Числа (сложение)
LOCAL nValue := 10
? SQRT(nValue += 15) // Результат: 5
? nValue // Результат: 25
- присваивание с конкатенацией и вычитанием:
// Символы (конкатенация)
LOCAL cString := "Привет "
? cString -= "Вам" // Результат: Привет Вам
// Дата (вычитание)
LOCAL dDate := CTOD("12/24/90")
dDate -= 12 // Результат: 12/12/90
// Числа (вычитание)
LOCAL nValue := 10
? newValue := (nValue -= 5) ** 2 // Результат: 25
? nValue // Результат: 5
- присваивание с умножением:
LOCAL nValue := 10
? newValue := (nValue *= 5) + 100 // Результат: 150
? nValue // Результат: 50
- присваивание с модулем:
LOCAL nValue := 10
? newValue := (nValue %= 4) * 100 // Результат: 200
? nValue // Результат: 2
- присваивание с экспонентой:
LOCAL nValue := 10
? newValue := (nValue **= 3) + 50 // Результат: 1050
? nValue // Результат: 1000
-------------------------------------------------------------------
314
Специальные операторы
-------------------------------------------------------------------
Специальные операторы используют специальные знаки.
Следующая таблица показывает используемые специальные операторы.
__________________________________________________
Символ Назначение
__________________________________________________
& Макро-оператор
-> Оператор алиаса
@ Оператор для передачи значения
по ссылке
{ } Определение буквенного массива
или определения блока
[ ] Определение элемента массива
( ) Функция или определение группы
операторов
____________________________________________________
Пример использования использования макро-оператора:
- простейшее применение макро-оператора:
cMacro := "Вам "
? "Привет &cMacro" // Результат: Привет Вам
bBlock := &("{ |exp| QOUT(exp) }")
.
.
EVAL(bBlock, DATE())
- применение макро-оператора для создания массивов:
cName := "aArray"
nElements := 5
cNameElement := "aArray[1]"
//
PRIVATE &cName.[nElements] // Создание "array" с 5 элементами
&cNameElement. := 100 // Присваивание 100 элементу 1
&cName.[3] := "abc" // Присваивание "abc" элементу 3
- применение вложенных макро-операторов:
cOne = "&cTwo"
cTwo = "cThree"
cThree = "Привет"
//
315
? &cOne // Результат: "Привет"
Пример использования использования алиаса:
- использование алиаса для доступа к другой рабочей области:
USE Customer NEW
USE Invoices NEW
? Customer->CustName // Результат: Bill Smith
? Customer->(RECNO()) // Результат: 1
? Customer->(FOUND()) // Результат: .F.
- использование алиаса для ссылки на переменные поля и памяти:
USE Customer NEW
MEMVAR->CustName = "Bill Smith" // Создание переменной памяти CustName
LOCATE FOR MEMVAR->CustName = FIELD->CustName
Пример использования отличий между передачей аргументов пользовательской
функции по ссылке и по значению:
x := 100
MyFunc(@x) // Передача по ссылке
? x // Результат: 10
x := 100
MyFunc(x) // Передача по значению
? x // Результат: 100
FUNCTION MyFunc( nNumber )
nNumber := SQRT( nNumber )
RETURN nNumber
Пример использования использования {} :
- определение элементов массива:
LOCAL aPerson := { "Имя", "Адрес", DATE() }
STATIC aNumList := { 1, 2, 3, 4, 5, 6, 7, 8 }
- создание нескольких массивов:
aMulti := { {1, 2, 3}, {"A", "B", "C"} }
- определение блока:
LOCAL bSayBlock
bSayBlock := { |x| QOUT(x) }
EVAL(bSayBlock, 10) // Result: 10
, DATE() }