Operators - HimxhMC/HimDSL GitHub Wiki

运算符 / Operators

本章内容 / What This Chapter Covers

到目前为止,示例里已经出现了 +、<、&&、++ 这些符号,本章把它们系统地讲一遍。你会看到四类运算符:算术、比较、逻辑、赋值。每一类都配上可以直接运行的例子。

So far you have seen +, <, &&, ++ in examples. This chapter presents them systematically: four categories — arithmetic, comparison, logical, and assignment — each with runnable examples.


算术运算符 / Arithmetic Operators

算术运算符有五个:

There are five arithmetic operators:

运算符 含义 示例 结果
+ 加法 5 + 3 8
- 减法 5 - 3 2
* 乘法 5 * 3 15
/ 除法 6 / 3 2
% 取模 7 % 3 1
int a = 5 + 3;      // 8
int b = 5 - 3;      // 2
int c = 5 * 3;      // 15
int d = 6 / 3;      // 2
int e = 7 % 3;      // 1

整数除法 / Integer Division

当两边都是整数时,/ 执行整数除法,结果向零截断,小数部分直接丢弃:

When both operands are integers, / performs integer division: the result truncates toward zero and the fractional part is dropped:

int a = 7 / 2;      // 3,不是 3.5
int b = -7 / 2;     // -3,向零截断
double c = 7 / 2.0; // 3.5,只要一边是 double 就走浮点
double d = 7.0 / 2; // 3.5

算比例的时候要特别小心。想得到 2.5 就写 5.0 / 2,不能写 5 / 2。

Be careful with ratios. To get 2.5, write 5.0 / 2, not 5 / 2.

取模 / Modulo

% 求两个数相除的余数。常用于判断奇偶、循环取整:

% returns the remainder of a division. Common for parity checks and cyclic indices:

int a = 7 % 3;      // 1
int b = 8 % 3;      // 2
int c = 9 % 3;      // 0

// 判断偶数
if (n % 2 == 0) {
    runcmd("CONSOLE", "say " + n + " 是偶数");
}

负数取模的符号跟被除数一致,这一点在处理坐标或循环索引时可能踩坑。

Modulo with negatives keeps the sign of the dividend — a pitfall when dealing with coordinates or cyclic indices.

字符串拼接 / String Concatenation

当 + 的一边是字符串,它会执行拼接而不是加法:

When one side of + is a string, it concatenates instead of adding:

string s = "玩家 " + "Steve";      // "玩家 Steve"
string t = "血量: " + 20;          // "血量: 20"
string u = 1 + " + " + 2;          // "1 + 2"(不是 3)

注意第三条:表达式是从左往右执行的。1 + " + " 先算,得到字符串 "1 + ";再和 2 拼,得到 "1 + 2"。如果你希望先算 1 + 2 再拼,必须加括号:

Note the third line: expressions evaluate left to right. 1 + " + " runs first, yielding the string "1 + ", then it concatenates with 2 to give "1 + 2". To force 1 + 2 first, add parentheses:

string v = (1 + 2) + " items";     // "3 items"

比较运算符 / Comparison Operators

比较运算符返回布尔值:

Comparison operators return a boolean:

运算符 含义
== 等于
!= 不等于
< 小于
> 大于
<= 小于等于
>= 大于等于
bool a = 5 == 5;      // true
bool b = 5 != 3;      // true
bool c = 5 < 3;       // false
bool d = 5 >= 5;      // true

数字与字符串 / Numbers vs Strings

两个数字之间按数值比较;其他情况按字符串字典序比较:

Two numbers compare numerically; everything else compares lexicographically:

bool a = 5 == 5.0;    // true,数值相等
bool b = "abc" < "abd"; // true,字典序
bool c = 10 < 2;      // false,数值比较
bool d = "10" < "2";  // true,字符串比较,按字符 '1' < '2'

最后两行是个经典坑:数字比较和字符串比较的结果完全相反。从命令拿到的参数默认是字符串,如果要做数字比较,先 toInt:

The last two lines are a classic trap: numeric and string comparison can give opposite results. Command-line arguments arrive as strings, so convert with toInt before numeric comparison:

int main(string n) {
    int v = toInt(n);
    if (v > 10) {
        runcmd("CONSOLE", "say 大于 10");
    }
}

用户枚举的比较 / Comparing User Enums

用户枚举可以和字符串直接比较,写起来更自然:

User enums compare directly with strings, which reads more naturally:

enum Color { RED, GREEN, BLUE };

int main() {
    var c = Color.RED;
    if (c == "RED") {
        runcmd("CONSOLE", "say 是红色");
    }
}

逻辑运算符 / Logical Operators

三个逻辑运算符:

Three logical operators:

运算符 含义
&& 与(都真才真)
|| 或(一个真就真)
! 非(取反)
bool a = true && false;    // false
bool b = true || false;    // true
bool c = !true;            // false

组合使用时要加括号:

Parenthesize when combining:

if ((hp < 10 || hungry < 6) && alive) {
    runcmd("CONSOLE", "say 需要治疗");
}

短路求值 / Short-Circuit

&& 和 || 支持短路求值:左边能决定结果时,右边不会执行。

&& and || short-circuit: if the left side already determines the result, the right side does not run.

// 安全:如果 players 为空,size() 返回 0,左边为假,右边不执行
if (players.size() > 0 && players.get(0) != null) {
    // ...
}

利用这一点可以避免越界。上面的例子中,如果 players 是空列表,players.get(0) 会报错;但由于 && 的短路特性,右边根本不会执行。

This property helps avoid out-of-bounds errors. In the example above, if players is empty, players.get(0) would error — but short-circuit prevents the right side from ever running.

反过来,|| 也可以用来写默认值:

Conversely, || can serve as a default fallback:

string name = $player(p, name)$;
if (name == null || name == "") {
    name = "未知玩家";
}

自增与自减 / Increment and Decrement

++ 和 -- 是自增自减运算符,等价于 x = x + 1 和 x = x - 1。可以放在变量前(前缀)或后(后缀)。

++ and -- increment and decrement, equivalent to x = x + 1 and x = x - 1. They may precede (prefix) or follow (postfix) the operand.

int i = 5;
i++;        // i 变成 6
i--;        // i 变回 5
++i;        // i 变成 6
--i;        // i 变回 5

前后缀在单独作为一条语句时效果完全相同。区别在于表达式里:

Prefix and postfix are identical when used as a standalone statement. The difference appears inside expressions:

int i = 5;
int a = i++;    // a = 5,然后 i = 6(先取值后自增)
int b = ++i;    // i = 7,然后 b = 7(先自增后取值)

因为这点区别很容易让人读错,推荐只用单独语句形式(i++;),把自增作为其他表达式的一部分留给真正需要的人。

Because the distinction is easy to misread, prefer the standalone form (i++;) and leave expression-embedded increment to those who truly need it.

++ 和 -- 可以用在变量、数组元素、结构体字段上:

++ and -- also work on variables, array elements, and struct fields:

arr[0]++;
s.count++;

但不能用在常量或表达式上:

But not on constants or expressions:

5++;              // ✗
a + b++;          // ✗ 不是合法的 lvalue

复合赋值 / Compound Assignment

当一个变量要基于自身的旧值做运算,复合赋值能写得更短:

When a variable is updated based on its own old value, compound assignment is shorter:

复合写法 等价写法
x += 5 x = x + 5
x -= 5 x = x - 5
x *= 5 x = x * 5
x /= 5 x = x / 5
x %= 5 x = x % 5
int score = 0;
score += 10;        // 10
score += 20;        // 30
score -= 5;         // 25
score *= 2;         // 50

复合赋值对数组元素和字段同样有效:

Compound assignment also works on array elements and fields:

arr[0] += 3;
s.count -= 1;

+= 也支持字符串拼接:

+= also concatenates strings:

string msg = "玩家";
msg += " Steve";
msg += " 上线了";      // "玩家 Steve 上线了"

位取反 / Bitwise NOT

~ 是位取反运算符,把整数按二进制逐位取反。日常脚本里很少用,一般在处理标志位或底层数据时才会遇到。想了解的话,可以把它理解成 ~x = -x - 1。

~ is the bitwise NOT operator, flipping every binary bit of an integer. It is rare in everyday scripts, appearing mostly for flags or low-level data. As a mental model, ~x = -x - 1.

int a = ~0;         // -1
int b = ~5;         // -6

没有对应的 &、|、^ 位运算符,需要的话得借助 Java 反射调用。

There are no &, |, or ^ bitwise operators; use Java reflection if you need them.


优先级 / Precedence

运算符优先级从高到低:

Precedence from high to low:

  1. ! -(一元) ~ ++ --
  2. * / %
  3. + -
  4. < > <= >=
  5. == !=
  6. &&
  7. ||

实践中不要背优先级。写复杂表达式时主动加括号,让意图一目了然:

In practice, do not memorize precedence. When writing a complex expression, add parentheses to make the intent clear:

// 难以判断
if (a && b || c && d) { ... }

// 一目了然
if ((a && b) || (c && d)) { ... }

括号可能多打几个字,但换来的可读性和确定性远远值得。

Parentheses may cost a few keystrokes but buy readability and certainty.


小结 / Summary

  • 算术:+ - * / %,整数除法向零截断。

  • 字符串拼接用 +,从左往右结合。

  • 比较:== != < > <= >=,数字按数值,其他按字符串。

  • 逻辑:&& || !,支持短路求值。

  • 自增自减:++ --,推荐单独使用。

  • 复合赋值:+= -= *= /= %=,也支持字符串。

  • 复杂表达式主动加括号。

  • Arithmetic: + - * / %; integer division truncates toward zero.

  • Concatenation with +, left-associative.

  • Comparison: numbers numerically, others lexicographically.

  • Logical: && || !, short-circuit.

  • Increment/decrement: ++ --; prefer standalone form.

  • Compound assignment: += -= *= /= %=; strings too.

  • Parenthesize complex expressions.


下一步 / Next Steps

下一章 [字符串与字符 / Strings-and-Chars] 讲解字符串的常用方法:取长度、查找、替换、分割、大小写转换,以及字符与字符串的区别。

Next, [字符串与字符 / Strings-and-Chars)] covers common string operations: length, search, replace, split, case conversion, and the distinction from characters.


⚠️ **GitHub.com Fallback** ⚠️