编程
Fundamentals
Setting Up Development Environment
UnigineScript
High-Level Systems
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
应用程序接口
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
Rendering-Related Classes

运算符

如果存在变量,就可使用这些变量进行操作。为了能达到这样的目的,UnigineScript将运算符进行了集成。大多数的运算符 都是符合,但这些符号并不是字母表上的部分符号而是可在键盘上使用的变量符号。

数字运算符

操作类型 运算符 类型 描述 运算对象类型
取反 - 一元运算符 返回一个与运算对象相反的值(changes its sign to the opposite) 标量矢量
增量 ++ 一元运算符 将运算对象的值加1 (支持前缀表示法及后缀表示法) 标量
减量 -- 一元运算符 将运算对象的值减1 (支持前缀表示法及后缀表示法) 标量
乘法 * 二元运算符 两个运算对象相乘 标量矢量
除法 / 二元运算符 用第二个运算对象除以第一个运算对象 标量矢量
模运算 % 二元运算符 将第二个运算对象除以第一个运算对象的余数返回 整型长整型浮点型双精度型
加法 + 二元运算符 将两个运算对象相加 标量矢量字符串
减法 - 二元运算符 将两个运算对象相减 标量矢量

源代码 (UnigineScript)
int a = 0, b = 0;
log.message("%d %d\n",++a,b++);
log.message("%d %d\n",++a,b++);
log.message("%d %d\n",a,b);

/* Output:
 * 1 0
 * 2 1
 * 2 2
 */

标量运算对象

所有采用两种不同运算对象类型的数字运算符会执行标量的自动转换。转换的结构通常为两种类型中范围最大的类型。

矢量运算对象

一些数字运算符会被运用到矢量类型。所有矢量类型可与相同类型的另一个运算对象进行添加,减法操作,乘法操作。而在不同类型的矢量运算对象或矢量甚至标量上进行运算时,仅可使用指定的结合运算符,因为大多数情况下矢量类型不可转换

第一个运算对象 运算符 第二个运算对象 结果
所有矢量类型:
vec3
vec4
dvec3
dvec4
ivec3
ivec4
mat4
dmat4
quat
+
-
*
与第一个运算对象相同 运算对象类型
vec3
vec4
dvec3
dvec4
ivec3
ivec4
/ 与第一个运算对象相同 运算对象类型
所有矢量类型:
vec3
vec4
dvec3
dvec4
ivec3
ivec4
mat4
dmat4
quat
*
/
整型 第一个运算对象类型
vec3
vec4
dvec3
dvec4
mat4
dmat4
quat
*
/
长整型
浮点型
第一个运算对象类型
dvec3
dvec4
mat4
dmat4
quat
*
/
双精度型 第一个运算对象类型
vec3 *
/
双精度型
dvec3
dvec3
vec4 *
/
双精度型
dvec4
dvec4
vec3 +
-
dvec3 dvec3
vec4 +
-
dvec4 dvec4
dvec3 *
/
+
-
vec3 dvec3
dvec4 *
/
+
-
vec4 dvec4
mat4 * vec3
vec4
dvec3
dvec4
dmat4
第二个运算对象类型
mat4
dmat4
* quat 第一个运算对象类型
dmat4 * vec3
dvec3
dvec3
dmat4 * vec4
dvec4
dvec4
dmat4 * mat4 dmat4
quat * vec3
vec4
dvec3
dvec4
mat4
dmat4
第二个运算对象类型

字符串运算符

这些运算符仅将 字符串 变量作为运算对象。

运算类型 运算符 类型 描述
字符串连接 + 二元运算符 两个运算对象被连接成一个字符串

字符串不仅可与字符串连接在一起,并且由于强制转换类型其还能与任意基本类型的变量连接在一起。

源代码 (UnigineScript)
float a = -3.9;
string str = "there can be a mixture";
str = str + " of integer (" + 56 + ") and floating point values (" + a + ")";
log.message("%s\n", str);

/* 输出: 
 * there can be a mixture of integer (56) and floating point values (-3.9)
 */

逻辑运算符及位运算符

这些运算符仅将下列类型的变量作为运算对象:

运算 运算符 类型 描述 运算对象类型
逻辑非 ! 二元运算符 将布尔表达式取反 整型长整型
逻辑与 && 二元运算符 如果两个运算对象为,则为 整型长整型
逻辑或 || 二元运算符 如果一个或两个运算对象为,则为 整型长整型
按位取否 (补数) ~ 二元运算符 对每个位逻辑取反 整型长整型
按位与 & 二元运算符 对相应的每一对位进行逻辑与运算 整型长整型
按位或 | 二元运算符 对相应的每一对位进行逻辑或运算 整型长整型
按位异或 ^ 二元运算符 对相应的每一对位进行逻辑异或运算 整型长整型
左移 << 二元运算符 使用由第二个运算对象指定的位数量将第一个运算对象中的位模式移至左侧 整型长整型
ivec3ivec4 也可为第一个运算对象
右移 >> 二元运算符 使用由第二个运算对象指定的位数量将第一个运算对象中的位模式移至右侧 整型, 长整型
ivec3ivec4 也可为第一个运算对象

所有非0的值等同于, 但如果需要为某些运算的结果返回为,通常使用 1 通常使用 0

注意
当需要对有逻辑运算符的表达式进行评估时,通常使用短路评估。即如果第一个计算对象无法用来决定整个表达式的值时,就使用第二个运算对象进行估值。但如果整个表达式都被包含在花括号中,此时会对所有运算对象估值。

比较运算符

注意
两个浮点型数字会被认为相等,如果这两个数字之间的差值小于1E-6。

运算类型 运算符 描述 运算对象类型
相等 == 检测两个运算对象是否相等 标量,矢量,字符串
整型(0) 可被比作空字符串 和v.v.
不相等 != 检测两个运算对象是否不相等 标量,矢量,字符串
整型(0) 可被比作空 字符串 和 v.v.
小于 < 检测第一个运算对象是否比第二个运算对象小 标量,字符串
大于 > 检测第一个运算对象是否比第二个运算对象大 标量,字符串
小于等于 <= 检测第一个运算对象是否小于等于第二个运算对象 标量,字符串
大于等于 >= 检测第一个运算对象是否大于等于第二个运算对象 标量,字符串

如果语句为,运算符返回1,否则就返回0

赋值运算符

运算类型 运算符 类型 描述
赋值 = 二元运算符 将第二个运算对象的值赋给第一个运算对象
"If-then-else" 替换 ? : 三元运算符 如果整个表达式为第二个赋值的运算对象,可用于条件赋值

条件运算符?: 可作为"if-then-else"结构中单行模块内容的简写进行使用。如果使用得当,此运算符可增加代码的可读性。其语法如下:test_expression1 ? then_expression : else_expression

源代码 (UnigineScript)
int a = 10;
int b;
b = (a > 9) ? 100 : 200; // 三元运算符的用法

// 此表达式等同于上一个表达式
if(a > 9) {
	b = 100;
} else {
	b = 200;
}
log.message("b =" + (b))
/* 输出:
 * b = 200
 */

也可在表达式内使用 ?:运算符。例如:

源代码 (UnigineScript)
int a = 1;
int b = 2;
int c = 3;
int d = 4;

log.message("%s\n","test 1: " + (a == b) ? "a == b" : "a != b" + " final");
log.message("%s\n","test 2: " + ((c == d) ? "c == d" : "c != d") + " final");
log.message("%s\n","test 3: " + (a == b) ? "a == b and " + ((c == d) ? "c == d" : "c != d") : ("a != b and " + ((c == d) ? "c == d" : "c != d")));
示例的输出结果为:
输出
test1: a != b final
test2: c != d final
test3: a != b and c != d

赋值运算符 = 可与 +-*/%&|^结合使用。 这些合并运算符(+=-=*=/=%=&=|=^=) 会将运算结果赋值给第一个运算对象(此对象必须为变量)。

注意
UnigineScript不支持在一个表达式内存在多个赋值情况:
源代码 (UnigineScript)
int a = 10;
int b, c;
a = b = c; // 此语句不会得以执行
a = b += c; // 此语句也不会得以执行

访问运算符

运算类型 运算符 类型 描述
访问成员 . 二元运算符 访问第一个运算对象的成员(第二个运算对象)。可随同下列对象一起使用:
范围解析 ::
  • 一元运算符 - 用于使用全局范围的标识符
  • 二元运算符 - 用于使用类或命名空间范围的标识符(类/命名空间成员)。
在标识符范围外对其进行访问。欲了解细节,请参看范围解析运算符
使用索引进行访问 [] 二元运算符 通过元素索引对其进行访问。可随同类,矢量,贴图,vec3vec4mat4quat一起使用

类型测试运算符

类型测试运算符用来检测所给变量的类型。 在下列情况下,运算符会返回1

  • 所给变量属于某种规定的类型
  • 所给对象是某个指定类的实例
  • 所给对象是某个类的实例,这个类由某个指定类派生而来

此运算符的语法如下:

源代码 (UnigineScript)
i is int

注意
第二个仅可是特定类型或类的名称,即:
  • 标量类型的一种
  • 矢量类型的一种
  • 字符串
  • 用户定义的类的名称
  • 外部类的名称

例如此运算符可在if-else语句中使用:

源代码 (UnigineScript)
class Foo { };

class Bar : Foo { };

void check(int v) {
	string s = typeinfo(v);
	// is 运算符和is_int()函数都会检查v是否为整型
	if(v is int) log.message("%s is int\n",s);
	if(is_int(v)) log.message("%s is int\n",s);
	// 检查v是否为浮点类型
	if(v is float) log.message("%s is float\n",s);
	if(is_float(v)) log.message("%s is float\n",s);
	// 检查v是否为Stream类或由Stream派生类的实例
	if(v is Stream) log.message("%s is Stream\n",s);
	// 检查v是否为File类的实例
	if(v is File) log.message("%s is File\n",s);
	// 检查v是否为Foo或Bar类的实例
	if(v is Foo) log.message("%s is Foo\n",s);
	// 检查v是否为Bar类的实例
	if(v is Bar) log.message("%s is Bar\n",s);
}

check(1);
check(1.0f);
check(new File());
check(new Foo());
check(new Bar());
输出内容如下:
输出
int: 1 is int
int: 1 is int
float: 1 is int
float: 1 is int
File 000000000E9330E0 internal (5:0:0) is Stream
File 000000000E9330E0 internal (5:0:0) is File
Foo 000000000D06FCD0 (131072:0:0) is Foo
Bar 000000000D06FD00 (196608:0:0) is Foo
Bar 000000000D06FD00 (196608:0:0) is Bar

运算符的优先顺序

如果表达式内有数个运算符,程序会按照如下表所列的优先顺序进行处理,优先级按照从上至下的顺序由高到低。

运算类型 运算符
括号 ()
访问运算符 [] .
一元运算符 ! - + ++ --
乘法运算符 * /
加法运算符,字符串连接 + -
移位运算符 << >>
比较运算符 == != < > <= >=
按位取否 ~
按位与 &
按位异或 ^
按位或 |
逻辑非 !
逻辑与 &&
逻辑或 ||
赋值运算符 = += -= *= /= %= &= |= ^= ?:

运算符重载

在此处了解运算符重载

最新更新: 2017-07-03