CN-Language中文编程语言:第03篇-语法基础

用中文写代码(三):一小时读完 CN 语法基础

前两篇我们认识了 CN 语言、跑通了第一个程序。今天把过程式编程的全部基础一次讲完:变量、类型、运算符、控制流、函数、数组、字符串、结构体、枚举。读完这篇,你就能动手写正经的 CN 程序了。

老规矩:以下所有示例都来自官方文档,逐个经过编译器编译、运行、输出比对,标注的输出就是真实运行结果。

一、程序的骨架

CN 源文件 UTF-8 编码、.cn 扩展名,入口是名为「主」的函数:

文件:骨架.cn

复制代码
// 单行注释
/* 块注释,支持嵌套 /* 像这样 */ */

静态 整32 全局计数 = 0;      // 全局静态变量(零初始化)

不安全 函数 主() -> 整32 {    // 静态变量写=不安全操作(进阶篇细讲)
    全局计数 = 全局计数 + 1;
    打印("计数:", 全局计数);
    返回 0;                   // 0 = 成功
}

运行输出:计数:1

  • 每条语句必须以分号结束------和 C/Rust 一样,没有 Python 那种「自动补分号」;
  • 顶层由函数、结构体、枚举、类、导入、全局变量声明组成。

二、变量:不初始化就不让用

文件:变量.cn

复制代码
函数 主() -> 整32 {
    整32 甲 = 10;            // 显式类型
    变量 乙 = 20;            // 类型推断(= 整32)
    浮64 单价 = 9.5;
    布尔 通过 = 真;
    字符 等级 = '甲';        // Unicode 字符(4 字节码点)
    甲 = 甲 + 乙;            // 赋值
    打印(甲, " ", 单价, " ", 通过, " ", 整32(等级));  // 字符打印=码点
    返回 0;
}

运行输出:30 9.500000 真 30002

  • 声明即初始化 是 CN 的默认姿势:未初始化的局部变量读取是编译错误------垃圾值根本没机会出现(编译期数据流检查,零运行时成本);
  • 变量 乙 = 20; 让编译器自己推断类型;
  • 字符是 4 字节 Unicode 码点,「甲」的码点就是 30002;
  • 常量 尺寸 = 4; 定义编译期常量,还能写算术表达式(常量 尺寸2 = 尺寸 * 2;);静态 变量零初始化、生存期=整个进程。

三、类型全景:从整8到整128

  • 整数 10 种:有符号 整8/整16/整32/整64/整128,无符号 正8/正16/正32/正64/正128;
  • 浮点 2 种:浮32/浮64(IEEE 754 单/双精度);
  • 其他:布尔(真/假)、字符(4 字节码点)、字符串(UTF-8)、空类型;
  • 还有两个中文习惯别名:整数=整32、小数=浮64。

文件:字面量.cn

复制代码
函数 主() -> 整32 {
    整32 十进制 = 42;
    整32 十六进制 = 0xFF;       // 255
    整32 二进制 = 0b1010;       // 10
    整32 八进制 = 0o777;        // 511
    整64 长值 = 100L;           // L 后缀 → 整64
    浮32 单精度 = 1.5f;         // f 后缀 → 浮32
    浮64 科学 = 1.5e10;
    打印(十进制, " ", 十六进制, " ", 二进制, " ", 八进制);
    打印(长值, " ", 单精度, " ", 科学);
    返回 0;
}

运行输出:42 255 10 511
100 1.500000 15000000000.000000

给追求细节的读者:同宽窄整数算术保持窄域 (整8 + 整8 = 整8,127+1 按两补码回绕成 -128);字面量超范围直接编译拒绝(整16 甲 = 40000; 不放行)。

四、类型转换:变窄必须明说

宽化(小类型转大类型)隐式进行;窄化、跨符号、浮点转整数,一律显式写 类型名(表达式),语义是位模式变换(Rust 的 as 同款):

文件:转换.cn

复制代码
函数 主() -> 整32 {
    整32 小 = 7;
    整64 大 = 小;                // 宽化:隐式放行
    浮64 比例 = 浮64(小) / 4;    // 显式转浮点 → 1.75
    整32 截断 = 整32(3.99);      // 浮转整:截断 → 3
    正64 位模式 = 正64(整32(-1)); // 升宽:符号扩展 → 2^64-1
    打印(大, " ", 比例, " ", 截断, " ", 位模式 == 18446744073709551615);
    返回 0;
}

运行输出:7 1.750000 3 真

五、运算符:C 风格全套

文件:运算符.cn

复制代码
函数 正数(整32 x) -> 布尔 { 返回 x > 0; }

函数 主() -> 整32 {
    整32 a = 7;
    整32 b = 2;
    打印(a + b, a - b, a * b, a / b, a % b);   // 9 5 14 3 1
    打印(a << 1, a >> 1, a & 3, a | 8, a ^ 1); // 14 3 3 15 6
    打印(a > b, a == 7, a != 7, !正数(-1));    // 布尔族
    整32 c = a > b ? a : b;                     // 三元(右结合)
    a += 10;                                    // 复合赋值族 += -= *= /= %=
    a++;                                        // 后缀自增:表达式值=原值
    打印(c, a);
    返回 0;
}
  • / 对整数是截断除;% 取余;除零=运行时错误(常量除零=编译错误);
  • 逻辑 && || 短路求值;位运算只对整型开放;
  • 后缀 a++ 的表达式值是自增前的原值,前缀是自增后的新值;
  • 顺带一个细节:打印的多个参数是紧挨着输出的 (所以上面 交换 后输出「21」),想要空格得自己打 打印(p, " ", q)。

六、控制流:如果/当/循环/选择/遍历

条件的小括号可以省略------「如果 分 >= 90」直接写:

文件:条件与循环.cn

复制代码
函数 分级(整32 分) -> 字符串 {
    如果 分 >= 90 {
        返回 "优";
    } 否则 如果 分 >= 60 {
        返回 "及格";
    } 否则 {
        返回 "不及格";
    }
}

函数 主() -> 整32 {
    打印(分级(95), " ", 分级(70), " ", 分级(30));

    整32 i = 0;
    当 i < 3 {                 // 当循环(前测)
        打印行(i, " ");
        i++;
    }
    打印("");

    循环 (整32 j = 10; j >= 0; j -= 5) {   // for 风格
        打印行(j, " ");
    }
    打印("");
    返回 0;
}

运行输出:优 及格 不及格
0 1 2
10 5 0

注意 打印行 输出不换行 ,打印 输出完自动换行。

更惊喜的是:字符串也能当选择条件,枚举成员还能裸写:

文件:选择.cn

复制代码
枚举 命令 { 启动, 停止, 查询 }

函数 主() -> 整32 {
    整32 键 = 2;
    选择 (键) {
        情况 0:
            打印("零");
            中断;
        情况 1, 2:            // 多值分组
            打印("一或二");
            中断;
        默认:
            打印("其他");     // 不写 中断 会贯穿下一分支(C 语义)
    }

    字符串 指令 = "开始";
    选择 (指令) {             // 字符串选择
        情况 "开始", "继续":
            打印("执行");
            中断;
        默认:
            打印("未知");
    }

    命令 c = 命令.查询;
    选择 (c) {                // 裸枚举成员
        情况 启动:
            打印("启动中");
            中断;
        情况 查询:
            打印("查询中");
            中断;
        默认:
            打印("...");
    }
    返回 0;
}

运行输出:一或二
执行
查询中

最后是遍历和循环控制:

文件:遍历与中断继续.cn

复制代码
函数 主() -> 整32 {
    整32[5] 数据 = {10, 20, 30, 40, 50};
    遍历 数据 中 每个 x {        // 数组遍历:x=元素副本
        打印行(x, " ");
    }
    打印("");

    循环 (整32 k = 0; k < 100; k++) {
        如果 k % 2 == 0 { 继续; }   // 跳过偶数
        如果 k > 10 { 中断; }        // 终止循环
        打印行(k, " ");
    }
    打印("");
    返回 0;
}

运行输出:10 20 30 40 50
1 3 5 7 9

  • 「遍历 数据 中 每个 x」------几乎就是中文句子;
  • 中断/继续 对应 break/continue;中断绑定最近一层循环或选择(与 C 的 break 一致);
  • 选择默认贯穿(fall-through),想停住必须显式写 中断。

七、函数:重载、默认参数、引用传递

文件:函数.cn

复制代码
// 重载:同名按参数类型与个数区分(仅返回类型不同不构成重载)
函数 最大(整32 a, 整32 b) -> 整32 { 如果 a > b { 返回 a; } 返回 b; }
函数 最大(浮64 a, 浮64 b) -> 浮64 { 如果 a > b { 返回 a; } 返回 b; }

// 默认参数:从右向左连续声明
函数 问候(字符串 名字 = "世界") -> 空类型 {
    打印("你好," + 名字);
}

// 引用参数:直写调用方
函数 交换(整32& a, 整32& b) -> 空类型 {
    整32 临时 = a;
    a = b;
    b = 临时;
}

// 常量引用参数:只读借用(体内赋值=编译错误)
函数 求和(常量 整64& x, 常量 整64& y) -> 整64 { 返回 x + y; }

函数 主() -> 整32 {
    打印(最大(3, 9), " ", 最大(2.5, 1.8));
    问候();
    问候("张三");
    整32 p = 1;
    整32 q = 2;
    交换(p, q);            // 引用实参:直传左值(不加 &)
    打印(p, q);
    整64 x = 100;
    整64 y = 23;
    打印(求和(x, y));      // 常量引用实参须左值变量
    返回 0;
}

运行输出:9 2.500000
你好,世界
你好,张三
21
123

还有泛型函数,编译期单态化,零运行时开销:

文件:泛型函数.cn

复制代码
泛型 <类型 T>
函数 交换泛型(T& a, T& b) -> 空类型 {
    T 临时 = a;
    a = b;
    b = 临时;
}

函数 主() -> 整32 {
    整32 甲 = 1;
    整32 乙 = 2;
    交换泛型<整32>(甲, 乙);      // 显式单态化<类型>;引用实参直传
    打印(甲, 乙);
    返回 0;
}

运行输出:21

八、数组:赋值即整块拷贝

数组写法是 类型[长度],长度可以是编译期常量表达式:

文件:数组.cn

复制代码
常量 行数 = 3;

函数 主() -> 整32 {
    整32[5] 表 = {10, 20, 30, 40, 50};   // 聚合初始化
    整32[行数] 零表;                      // 长度=常量表达式
    零表[0] = 7;
    打印(表[0], " ", 表[4], " ", 零表[0]);

    整32[3] 甲 = {1, 2, 3};
    整32[3] 乙 = 甲;                      // 整块值拷贝
    乙[0] = 99;
    打印(甲[0], " ", 乙[0]);              // 1 99(两态独立)

    整32 和 = 0;
    遍历 表 中 每个 x { 和 = 和 + x; }
    打印(和);
    返回 0;
}

运行输出:10 50 7
1 99
150

  • 下标从 0 起;越界读/写=运行时错误(错误码 2)直接终止;
  • 乙 = 甲 是整块值拷贝,改 乙 不影响 甲------两态独立;
  • 数组传给函数也是按值整块拷贝;要可变长度的动态容器,用标准库的 向量<T>。

九、字符串:拥有型 UTF-8

文件:字符串.cn

复制代码
函数 主() -> 整32 {
    字符串 名 = "CN 语言";
    打印(字符串长度(名));            // 9(UTF-8 字节:CN=2+空格1+语言=6)
    字符串 拼接 = "你好, " + 名 + "!" + 1;
    打印(拼接);                       // 你好, CN 语言!1
    打印(字符串包含(名, "语言"));     // 真
    打印(字符串子串(名, 3, 6));       // 语言(字节切片)
    打印(名[0]);                      // 67('C' 的 UTF-8 首字节)
    打印(字符串大写("cn"));           // CN
    返回 0;
}

运行输出:9
你好, CN 语言!1
真
语言
67
CN

  • 字符串是拥有型:数据在堆上,作用域结束自动释放(RAII),不用手动管内存;
  • 长度、下标、切片全部按 UTF-8 字节 口径------一个汉字 3 字节,字符串长度("中") 等于 3;
  • + 拼接时右侧数值自动转字符串("编号-" + 7 合法);
  • 字符串不可原地下标写(编译拒绝)------修改就是重建新串,杜绝改一半的中间态。

十、结构体与枚举

文件:结构体.cn

复制代码
结构体 点 {
    浮64 x;
    浮64 y;
}

结构体 线段 {
    点 起;      // 嵌套结构体字段
    点 止;
}

函数 主() -> 整32 {
    点 a = 点{x = 1.0, y = 2.0};
    点 b = a;               // 整体值拷贝
    b.x = 9.0;
    打印(a.x, " ", b.x);    // 1 9(两态独立)

    线段 线 = 线段{起 = 点{x = 0.0, y = 0.0}, 止 = 点{x = 3.0, y = 4.0}};
    浮64 dx = 线.止.x - 线.起.x;
    浮64 dy = 线.止.y - 线.起.y;
    打印(dx * dx + dy * dy);   // 25(3-4-5 直角三角形)
    返回 0;
}

运行输出:1.000000 9.000000
25.000000

  • 点{x = 1.0, y = 2.0} 是指定初始化器,带穷举纪律:缺字段、多写字段、重复字段都是编译错误------静默零填充这种坑在这里不存在;
  • 成员访问统一用点号;指针左侧自动解引用一级(p.x 等价 (*p).x),C 里的 -> 被废除了;
  • 结构体里有字符串、容器这类字段时,释放随作用域自动级联(RAII)。

枚举是命名常量族,成员可显式赋值(含负数),引用形态是 枚举名.成员,在选择的条件位可以裸写成员名(前面「选择.cn」已演示);枚举名::成员 是非法的------:: 保留给模块路径。

写在最后

到这里,过程式编程的地基打完了:变量、类型、转换、运算符、控制流、函数、数组、字符串、结构体、枚举。下一篇上强度:类与泛型------构造析构、继承与接口、泛型类、运算符重载,CN 面向对象的全套家伙什。

官方文档(本文整理自官方教程「语法基础」):www.cn-language.com/docs
源码仓库:gitcode.com/ChenChao_GitCode/CN_Language

这套中文语法读起来习惯吗?评论区聊聊你最意外的一个设计。

相关推荐
熊猫钓鱼>_>2 小时前
CMP for OpenHarmony 实战:Coil 图片加载库鸿蒙化使用心得
运维·服务器·开发语言·华为·ai编程·harmonyos·openharmony
fengci.2 小时前
CTF2刷题记录(困难部分)
android·开发语言·前端·学习·php
老王IT2 小时前
Rust开发环境搭建教程
开发语言·后端·rust
程序猿乐锅2 小时前
Streamlit 实现 AI 聊天 Agent:角色提示词、流式输出与会话管理
开发语言·前端·笔记·后端·python·学习
小南知更鸟2 小时前
【2026 年 Python 包管理工具选型:从“工具崇拜”回到工程约束】
开发语言·python
努力努力再努力wz3 小时前
【Lua入门系列】从动态类型到变量作用域:彻底理解 local、全局变量与跨文件访问
开发语言·junit·lua
程序猿乐锅3 小时前
面向对象练习:图书借阅系统里的封装、抽象类与多态
开发语言·前端·数据库·后端·python·学习·1024程序员节
沐晓时光3 小时前
C语言入门,深入理解指针(6)
c语言·开发语言
略略略咯咯3 小时前
33333
开发语言·windows·python