Skip to content

类型系统 ​

CIN 是静态类型语言:每个变量、参数与返回值都有确定类型,编译器据此选择指令 (整数用 ADD/MUL,浮点用 FADD/FMUL,字符串拼接用 STR_CONCAT)。 值模型很简单 —— 所有标量都占一个 64 位槽,所以没有 C 那样的宽度陷阱。

类型一览 ​

类型说明默认值
int64 位有符号整数0
char / short / long整数语法别名(存储仍是 64 位槽)0
unsigned int(及 unsigned char/short/long)无符号修饰(同 64 位槽,主要用于大数值字面量)0
float64 位 IEEE754 浮点0.0
bool布尔false
stringNUL 结尾字符串指针""
void仅函数返回类型-
StructName用户定义 struct全零
EnumName用户定义 enum(成员是编译期整数常量,类型名等价于 int)0
T[n] / T[n][m]固长数组(值语义)全零
T[] / int[][]指针形式数组(参数/返回)空指针

这张表给的是"类型的零值"

上表 默认值 一列描述类型本身的零值。局部变量能否真的拿到它取决于存储位置: 全局由数据区清零(可靠),局部固长数组与局部标量是栈帧残留值(不可靠), 局部 struct 则在进入块时分配并显式清零(可靠)。精确结论见下方 默认值表。

一句话记住宽度

char、short、long、unsigned 都只是语法别名:char c = 300 合法且 c 就是 300, 不存在 8 位截断或溢出回绕。需要"小整数"语义时自己用位运算或 % 约束范围。

整数类型与别名 ​

cin
function int_aliases() -> int {
    char c = 'A'              // 65
    char big = 300            // 合法: char 与 int 同宽
    short s = 2
    long l = 3
    unsigned int u = 4000000000
    unsigned long ul = 0xFFFFFFFF

    int total = c + big + s + l + (u % 1000)
    return total
}
写法解析结果备注
intint缺省整数类型
char / short / longint解析阶段直接折叠为 int
unsignedint缺省 unsigned 单独出现也合法
unsigned char/short/int/longint修饰词被接受但值模型不变

不要指望 char 做字节运算

char 不是字节类型。要处理字节请用 int + 位运算(& 0xFF), 读字符串得到的也是 0–255 的 int(见 字符串)。

浮点 ​

cin
float pi = 3.14159265
float tiny = 1e-5
float forced = 100f          // 100.0
float result = sqrt(16)      // 4 (打印时省略 .0)
  • float 是 64 位 IEEE754 双精度,字面量支持小数与科学计数法;
  • float_to_str(100.0) 打印为 100(去掉尾部 .0),float_to_str(1.5) 打印为 1.5;
  • / 运算恒为浮点除(见下文提升规则),整数除法用内建 idiv(a, b)。

布尔 ​

cin
bool ok = true
bool zero = 0                // false
bool five = 5                // true (非零即真)
println("ok = " + ok)        // ok = true
println("num = " + (true + true))   // num = 2
上下文truefalse
打印 / 字符串拼接"true""false"
数值运算(加减乘、比较、下标)10
条件(if / while / ?: / && / ||)真假
赋值给 int / float1 / 1.00 / 0.0
把 int 赋给 bool非零 → true0 → false

字符串 ​

string 变量持有指向 NUL 结尾字节序列的指针:

cin
string s = "hello"
int n = strlen(s)            // 5
int first = s[0]             // 104 ('h'), 只读
string t = s + " world"      // 拼接产生新堆块
  • 字符串不可原位修改:s[0] = 'H' 编译报错,要用 strcpy / substr / upper 等产生新串;
  • 字符串字段在 struct 里也是指针(见 struct);
  • 字符串内建函数清单见 内建函数。

void ​

void 只能作为函数返回类型,不能声明 void 变量:

cin
function greet() {           // 省略 -> void
    println("hi")
}

function greet2() -> void {  // 显式写 void
    println("hi")
}

struct 类型 ​

cin
struct Point {
    float x
    float y
}

struct Student {
    Point info               // 嵌套 struct (值内嵌)
    int grades[5]            // 固长数组字段
    float gpa
}
规则说明
字段类型标量、嵌套 struct、标量元素的固长数组;不能是 T[] 变长指针数组,也不能是 struct 元素的固长数组(Point items[3] 编译期报错,见 struct)
默认值全零(int 为 0、float 为 0.0、bool 为 false、数组全零)
语义整体赋值与返回是值拷贝,传参是引用可见(详见 struct)
访问p.x、s.info.name 链式成员访问

详见 struct。

enum 类型 ​

enum 为一组编译期整数常量命名; 枚举类型名本身等价于 int (Color c = BLUE 中的 c 就是一个 64 位整数槽, 默认值 0):

cin
enum Color { RED, GREEN = 5, BLUE }     // RED=0, GREEN=5, BLUE=6

Color c = BLUE
println(int_to_str(c))                  // 6
规则说明
声明位置文件顶层 (与 struct 同级), 语法 enum Name { 成员, ... }, 结尾分号可省略
自动递增未显式赋值的成员 = 上一个成员 +1; 第一个成员从 0 开始
显式赋初值= <整数常量表达式>: 支持 + - * / % << >> & | ^ 与一元 - / ~, 只能引用先前已定义的成员
语义成员是只读常量; 可用在表达式、全局初始化与 case 标签中
类型等价枚举类型名解析为 int (可作变量类型、参数类型、返回类型)
cin
enum Level { LOW = 1, MID = LOW + 4, HIGH = MID * 2 }   // 1, 5, 10

function rank(Level l) -> int {
    switch (l) {
        case LOW:  return 1
        case MID:  return 2
        default:   return 3
    }
}

成员不可赋值 (Cannot assign to enum member: X (constants are read-only)); 重复成员、空 enum、成员名与关键字/全局变量冲突、值超出 64 位都会在编译期报错。

数组类型 ​

固长数组 T[n] ​

cin
int a[5]                     // 一维, 全零
float m[3][4]                // 二维 (行主序)
int init[4] = {1, 2, 3, 4}   // 字面量初始化
int ident[2][2] = { {1, 0}, {0, 1} }

维度必须是整型常量表达式——字面量、const 命名常量、enum 成员与它们的算术组合:

cin
const int N = 4
enum Size { K = 3 }
int a[N]                // 4
int b[2 + 3]            // 5
int c[K + 1]            // 4
int grid[N][N]          // 二维用同一个常量

int a[PI](PI 是 float 常量)、int a[-1]、int a[x](x 是变量)都会在编译期报错, 不会静默变成 0 或别的长度。运行时长度请用指针形式 T[] + 长度变量。

  • 长度是类型的组成部分,声明后不可改变;
  • 下标从 0 开始,多维逐维下标 m[row][col];
  • 作参数时写 int[5],传入后衰减为指针形式(见 数组)。

指针形式数组 T[] ​

用于函数参数与返回值:

cin
function sum(int[] arr, int n) -> int {
    int s = 0
    for (int i = 0; i < n; i++) {
        s += arr[i]
    }
    return s
}

function make(int n) -> int[] {
    int[] r
    for (int i = 0; i < n; i++) {
        r[i] = i * i
    }
    return r
}

int[] 没有长度信息,必须另外传长度,否则越界不会被检查(默认无边界检查, 可用 --bounds-check 在编译期注入检查,与原生路径兼容)。

类型对照速查 ​

cin
int a[5]                     // 固长
function sum(int[] arr) -> int {
    return arr[0]
}

默认值表 ​

位置默认值是否可靠
全局变量int/char/short/long/unsigned → 0,float → 0.0,bool → false,string → 空串,struct/数组 → 全零可靠:数据区由运行时建好后全零
固长数组(全局声明)全零可靠
固长数组(局部声明)——不可靠:存在栈帧里且不发射清零代码,会读到上一次调用的残留值(见下方警告)
struct 变量(全局或局部)字段全零可靠:局部 struct 在进入块时分配对象并清零
局部标量变量框架内的残留值不可靠,见下方警告

局部固长数组和局部标量都不可靠

编译器在函数序言里只做栈指针下移,不发射清零代码。栈槽在同一进程内会被复用:

cin
function dirty() -> void {
    int a[4]
    a[0] = 111
    a[1] = 222
    a[2] = 333
    a[3] = 444
}

function main() -> int {
    dirty()
    int b[4]
    println(int_to_str(b[0] + b[1] + b[2] + b[3]))   // 不是 0 (实测 1110)
    return 0
}

需要确定初值时显式初始化:int b[4] = {0}。

局部标量变量同样不要依赖"默认值"

同一个原因在标量上更常见:

cin
function f() -> void {
    int p
    int q
    p = 777
    q = 888
}

function main() -> int {
    f()
    int p
    int q
    println("p=" + int_to_str(p) + " q=" + int_to_str(q))   // 可能是 p=777 q=888
    return 0
}

规则:局部变量总是先赋值再使用。 需要确定初值时显式写 int total = 0。

类型提升与截断 ​

运算结果类型说明
int 与 float 混算float整数侧自动 ITOF 提升
bool 与 float 混算floattrue → 1.0
int + - * % intint纯整数运算
任意 /恒为 float即使两侧都是整数,也是浮点除
移位 << >> & | ^ ~int只接受整数操作数
比较 == != < > <= >=bool结果作为值使用时是 1 / 0
&& || !bool短路求值
?: 三目两侧同为 int → int;任一侧 float → float;同为 string → string不允许 string 与数值混合
min / max任一侧 float → float,否则 int

截断规则 ​

转换行为
float → int(赋值 int i = f,或函数返回值/参数)向零截断:2.7 → 2,-2.7 → -2
int → bool非零为 true,零为 false(无指令开销)
bool → int / floattrue → 1 / 1.0
int / bool → floatITOF 提升
float → string需要显式内建 float_to_str(f)(拼接/打印时会自动字符串化)
cin
function conversions() -> int {
    float a = -2.7
    float b = 2.7
    int ia = a                  // -2  (向零截断)
    int ib = b                  //  2

    int q = -7 / 2              // -3  (浮点除 -3.5 再截断)
    int m = -7 % 2              // -1  (整除取模, 仅整数)

    bool t = 5                  // true
    bool f = 0                  // false
    int ti = t                  // 1
    float tf = t                // 1.0

    println("ia=" + int_to_str(ia) + " ib=" + int_to_str(ib)
            + " q=" + int_to_str(q) + " m=" + int_to_str(m))
    println("t=" + bool_to_str(t) + " ti=" + int_to_str(ti)
            + " tf=" + float_to_str(tf))
    return ia + ib + q + m
}
text
ia=-2 ib=2 q=-3 m=-1
t=true ti=1 tf=1

除法与取模对照 ​

cin
float x = 7 / 2              // 3.5
int y = 7 / 2                // 3   (3.5 截断)
int z = idiv(7, 2)           // 3   (显式整数除)
int r = -7 % 2               // -1

浮点取模会编译失败

7.5 % 2.0、f %= 2.0 都直接报 Float modulo not supported。 需要浮点取余时先用 floor 取整,或改用整数运算。

常见类型错误 ​

报错信息原因修正
Float modulo not supported对 float 用 %改用整数,或先 floor/ceil
Bitwise operator '&' requires integer operands (got float and int)位运算混入 float / string位运算仅限整数
Bitwise NOT '~' requires an integer operand~ 作用于 float / string同上
Switch expression must be integer, got: floatswitch 选择器是 float先转 int(截断)再 switch
Cannot mix string and numeric in '?:'三目两侧一侧 string 一侧数值统一转成 string 或数值
Type mismatch ...赋值 / 传参类型不兼容显式转换或用 int_to_str / float_to_str
Cannot apply '&=' to float对 float 用位运算复合赋值改用 + - * / 复合赋值
Cannot assign to enum member: X (constants are read-only)给 enum 成员赋值成员是编译期常量,改用普通 int 变量
Enum member X initializer must be an integer constant expressionenum 初值引用了变量/函数或未定义的成员只用整数常量与先前已定义的成员

相关页面 ​

文档由 VitePress 构建