CAPL 编程系列教程 - 第六期:复合数据类型之结构 (struct)

CAPL 编程系列教程的第六期内容,主要讲解 CAPL 中的另一种重要的复合数据类型:结构 (Structure),通常简写为 struct

CAPL 编程系列教程 - 第六期:复合数据类型之结构 (struct)

一、 课程回顾与本期目标

  • 回顾: 前面学习了 CAPL 的简单数据类型和数组(复合类型之一)
  • 本期目标: 学习 CAPL 中的结构 (struct),理解如何定义结构类型、声明结构变量、初始化以及访问其成员
  • 与 C 语言的关系: CAPL 中的结构语法与 C 语言中的结构完全相同

二、 结构 (struct) 的基本概念

  • 定义: 结构是一种复合数据类型,它允许将多个不同或相同类型的简单数据项组合成一个整体
  • 作用: 用于表示具有多个属性的实体,如一个点(有 x, y 坐标)、一个学生(有姓名、年龄)、一本书(有标题、价格)等,使数据组织更清晰、更有逻辑性
  • 成员 (Member): 结构中包含的各个数据项称为成员或属性
    • 每个成员都有自己的名称数据类型
    • 成员的数据类型可以各不相同,可以是简单类型(int, byte, float),也可以是数组(char name[50]),甚至可以是另一个结构类型

三、 定义结构类型 (Defining a Struct Type)

  • 语法:
    Code snippet
    struct TypeName {
        DataType1 memberName1;
        DataType2 memberName2;
        // ... more members
    }; // <-- 注意末尾的分号
    
  • 关键字: 使用 struct 关键字开始定义
  • 类型名称 (TypeName): 自定义的结构类型的名字(如 Point, Student, Hero, Book),推荐首字母大写
  • 成员定义: 在花括号 {} 内定义结构包含的成员,每个成员的定义方式类似普通变量声明 (DataType memberName;),每个成员定义后需加分号
  • 格式: 推荐将花括号和每个成员各占一行,并进行缩进,以提高可读性
  • 末尾分号: 整个结构类型定义结束后,必须在右花括号 } 后面加上一个分号 ;
  • 示例:
    Code snippet
    struct Point { // 定义点结构类型
        int x;      // x坐标成员 (int类型)
        int y;      // y坐标成员 (int类型)
    };
    
    struct Student { // 定义学生结构类型
        char name[50]; // 姓名成员 (字符数组/字符串)
        byte age;      // 年龄成员 (byte类型)
    };
    
    struct Hero { // 定义英雄结构类型
        char name[50]; // 姓名
        byte level;    // 等级
        struct Point coordinate; // 坐标成员 (Point结构类型)
    };
    
  • 重要: 这个步骤仅仅是定义了一种新的数据类型,并没有创建任何变量

四、 声明结构变量 (Declaring Struct Variables)

  1. 先定义类型,后声明变量 (推荐):
    • 语法: struct TypeName variableName;
    • 必须先使用 struct TypeName {...}; 定义好结构类型。
    • 然后使用 struct 已定义的类型名 变量名; 来声明该结构类型的变量
    • 示例: struct Point p1; 声明了一个名为 p1Point 结构变量
  2. 定义类型的同时声明变量:
    • 语法: struct TypeName {...} variableName1, variableName2, ...;
    • 在结构类型定义的右花括号 } 和末尾分号 ; 之间,直接写上要声明的变量名,可以声明一个或多个(用逗号隔开)
    • 示例: struct Student { ... } s1; 定义 Student 类型的同时声明了变量 s1
  3. 定义匿名结构并声明变量:
    • 语法: struct { ... } variableName1, variableName2, ...;
    • 在定义结构时省略类型名称,直接在花括号和分号之间声明变量
    • 优点: 语法简洁。
    • 缺点: 无法在其他地方再次使用这个(未命名的)结构类型来声明新的变量,只能在定义时一次性声明
    • 示例: struct { char title[50]; float price; } b1; 定义了一个匿名结构并声明了变量 b1

五、 初始化结构变量 (Initializing Struct Variables)

  1. 声明时不初始化:
    • 如果只声明变量而不进行初始化(如 struct Point p1;),则结构中所有成员的初始值默认为 0(或对应类型的零值)
  2. 声明时初始化:
    • 在声明变量的同时,可以使用花括号 {} 初始化列表来为成员赋值
    • 方法一 (按成员名称赋值 - 推荐):
      • 语法:struct TypeName var = { .memberName1 = value1, .memberName2 = value2, ... }; (CAPL 中通常省略成员名前的点 .) 或 struct TypeName var = { memberName1 = value1, memberName2 = value2, ... };
      • 在花括号内,使用 成员名 = 值 的形式,成员间用逗号 , 分隔。这种方式更清晰,不易出错
      • 示例: struct Point p2 = { x = 3, y = 7 }; (视频中示例,实际 CAPL 更常用不带 = 的方式,见方法二,但此方法在 C 中常见)。 修正/补充: CAPL 标准初始化方式是按顺序或使用指定初始化器(Designated Initializers),但视频中的 x=3 写法在 C 中用于指定初始化器,CAPL 可能不支持。更标准的 CAPL 初始化如下。
    • 方法二 (按成员顺序赋值):
      • 语法:struct TypeName var = { value1, value2, ... };
      • 在花括号内,按结构定义中成员的顺序依次提供值,用逗号 , 分隔
      • 示例: struct Point p3 = { 4, 5 }; // 4 赋给 x, 5 赋给 y struct Student s1 = { "张无忌", 25 };
      • 注意: 这种方法依赖于成员顺序,如果结构定义变化可能出错。
    • 结合匿名结构: 匿名结构也可以在声明时初始化,语法相同 struct { char title[50]; float price; } b1 = { "西游记", 128.5 };

六、 访问结构成员 (Accessing Struct Members)

  • 语法: variableName.memberName
  • 使用点运算符 . (英文句点) 来访问结构变量中的特定成员
  • 点运算符可以理解为中文的“的”
  • 用途:
    • 读取成员值: write("P1 的 x 坐标是 %d", p1.x);
    • 修改成员值: p1.x = 22; p1.y = 3;
  • 可以像操作普通变量一样对结构成员进行读写操作

七、 总结与后续

  • 结构是将相关数据组织在一起的有效方式
  • 需要区分定义结构类型声明结构变量
  • 掌握使用点运算符 . 访问结构成员的方法
  • 后续课程将继续讲解 CAPL 的其他内容。