【重拾C语言】八、表单数据组织——结构体(类型、类型别名、直接/间接访问;典例:复数、成绩单)

2024-07-30 08:52:07 浏览数 (1)

前言

C语言中,结构体(Structure)是一种自定义的数据类型,用于组织和存储不同类型的数据项。结构体允许我们将多个相关的数据项组合在一起,形成一个更复杂的数据结构。

八、结构体

8.1 结构体类型

  • 结构体类型的定义
    • 结构体类型是分量的集合
    • 分量也称成员、成分、域
    • 分量类型可以不同

C语言中,结构体类型的定义是使用struct关键字

结构体标签是用于标识结构体类型的名称。

在定义结构体类型时,可以在结构体内部声明多个成员变量,每个成员变量都有自己的数据类型。

名为Person的结构体类型,包含姓名、年龄和性别三个成员变量:

代码语言:javascript复制
struct Person {
    char name[50];
    int age;
    char gender;
};

结构体类型的定义通常放在程序的开头或者单独的头文件中,以便在需要使用结构体的地方可以直接引用。

8.2 结构体类型名

8.2.1 typedef关键字

typedef是C语言中的一个关键字,用于为已有的数据类型起一个新的名称(别名)。通过使用typedef,我们可以为现有的数据类型定义一个新的名称,以便在代码中更方便地使用。

typedef的语法形式是:

代码语言:javascript复制
typedef 原类型名 别名;

使用typedef来为int类型定义一个新的名称,比如叫做"myInt":

代码语言:javascript复制
typedef int myInt;

使用myInt来声明一个整数变量,就相当于声明一个int类型的变量:

代码语言:javascript复制
myInt num = 42;
8.2.1 结构体类型别名
代码语言:javascript复制
typedef struct Person {
    char name[50];
    int age;
    char gender;
} PersonType;

typedef关键字用于为struct Person类型定义了一个别名PersonType。现在可以使用PersonType作为结构体类型struct Person的替代名称。

8.3 结构体变量

  • 类型定义不分配存储空间,只说明一个数据类型的框架结构
  • 类型标识符只定义了一个数据类型的框架,不占用存储空间,只给相应类型起一个名字
  • 只有变量才具有实体,才能保存数据
  • 声明结构体变量,可以采取如下三种形式之一
8.3.1 使用结构体类型引用
代码语言:javascript复制
struct Person person1;  // 使用结构体类型引用声明结构体变量
person1.age = 25;
printf("Age: %dn", person1.age);

使用`struct`关键字加上结构体类型名称来声明结构体变量`person1`。然后,可以通过该变量访问结构体的成员。

8.3.2 使用结构体类型定义
代码语言:javascript复制
struct Person {
    char name[50];
    int age;
    char gender;
};

struct Person person2;  // 使用结构体类型定义声明结构体变量
person2.age = 30;
printf("Age: %dn", person2.age);

在声明结构体变量之前先定义了结构体类型`struct Person`,包括其成员。然后,我们可以使用该结构体类型来声明结构体变量`person2`。

8.3.3 使用typedef定义的结构体类型别名
代码语言:javascript复制
typedef struct {
    char name[50];
    int age;
    char gender;
} PersonType;

PersonType person3;  // 使用结构体类型别名声明结构体变量
person3.age = 35;
printf("Age: %dn", person3.age);

使用`typedef`关键字将匿名结构体类型定义为别名`PersonType`,然后使用`PersonType`来声明结构体变量`person3`。通过使用别名,我们可以直接访问结构体变量的成员。

8.4 访问结构体变量

8.4.1 直接成员选择表达式

直接成员选择表达式使用点号(.)来访问结构体变量的成员。

8.4.2 间接成员选择表达式——指向结构体变量的指针

通过指针可以方便地访问结构体的成员变量,可以使用箭头运算符 "->" 来访问指向结构体的指针所指向的成员变量。例如,如果有一个指向结构体的指针 ptr,并且结构体中有一个成员变量 member,我们可以使用 ptr->member 来访问该成员变量的值。

代码语言:javascript复制
#include <stdio.h>

// 定义一个结构体
struct MyStruct {
  int num;
  char letter;
};

int main() {
  // 声明一个结构体变量并初始化
  struct MyStruct myVar = {10, 'A'};
  
  // 声明一个指向结构体的指针,并指向 myVar
  struct MyStruct *ptr = &myVar;
  
  // 使用指针访问结构体成员变量
  printf("num: %dn", ptr->num);         // 输出:num: 10
  printf("letter: %cn", ptr->letter);   // 输出:letter: A
  
  return 0;
}
8.4.3 嵌套结构体

对于嵌套结构体,你仍然可以使用成员选择表达式来访问内层结构体变量的成员。无论是直接成员选择表达式还是间接成员选择表达式,都可以根据需要继续应用于内层结构体变量。

嵌套结构体:

代码语言:javascript复制
struct InnerStruct {
  int innerNum;
  char innerLetter;
};

struct OuterStruct {
  int outerNum;
  struct InnerStruct inner;
};

OuterStruct 包含一个整数类型的成员变量 outerNum 和一个嵌套的 InnerStruct 结构体变量 inner,而 InnerStruct 结构体又包含一个整数类型的成员变量 innerNum 和一个字符类型的成员变量 innerLetter

如果我们有一个嵌套结构体变量 myOuterVar,我们可以使用成员选择表达式来访问其中的成员变量。例如,要访问 outerNum,我们可以使用 myOuterVar.outerNum。要访问 innerNum,我们可以使用 myOuterVar.inner.innerNum。类似地,要访问 innerLetter,我们可以使用 myOuterVar.inner.innerLetter

代码语言:javascript复制
#include <stdio.h>

struct InnerStruct {
  int innerNum;
  char innerLetter;
};

struct OuterStruct {
  int outerNum;
  struct InnerStruct inner;
};

int main() {
  struct OuterStruct myOuterVar;

  // 设置外层结构体成员变量的值
  myOuterVar.outerNum = 10;

  // 设置内层结构体成员变量的值
  myOuterVar.inner.innerNum = 20;
  myOuterVar.inner.innerLetter = 'A';

  // 输出外层结构体成员变量的值
  printf("Outer Num: %dn", myOuterVar.outerNum);

  // 输出内层结构体成员变量的值
  printf("Inner Num: %dn", myOuterVar.inner.innerNum);
  printf("Inner Letter: %cn", myOuterVar.inner.innerLetter);

  return 0;
}

无论嵌套结构体有多深,都可以根据结构体成员的层次结构使用成员选择表达式来访问任意层级的成员变量。

8.5 程序设计实例

8.5.1 复数

复数(Complex number)是由实数部分和虚数部分组成的数。在程序设计中,我们可以使用结构体来表示复数,例如:

代码语言:javascript复制
struct Complex {
  double realPart;
  double imaginaryPart;
};

定义了一个名为 Complex 的结构体,它包含两个成员变量 realPartimaginaryPart,分别表示复数的实部和虚部。使用这个结构体,我们可以创建复数的变量并对其进行操作:

代码语言:javascript复制
#include <stdio.h>

struct Complex {
  double realPart;
  double imaginaryPart;
};

int main() {
  struct Complex myComplex;

  // 设置复数的实部和虚部
  myComplex.realPart = 3.0;
  myComplex.imaginaryPart = 4.0;

  // 访问并输出复数的实部和虚部
  printf("Real Part: %.2fn", myComplex.realPart);
  printf("Imaginary Part: %.2fn", myComplex.imaginaryPart);

  return 0;
}
8.5.2 成绩
代码语言:javascript复制
#include <stdio.h>
 
struct Score {
    char name[50];
    char subject[50];
    int score;
};
 
int main() {
    struct Score score1;
 
    printf("请输入姓名:");
    scanf("%s", score1.name);
 
    printf("请输入科目:");
    scanf("%s", score1.subject);
 
    printf("请输入成绩:");
    scanf("%d", &score1.score);
 
    printf("姓名:%sn", score1.name);
    printf("科目:%sn", score1.subject);
    printf("成绩:%dn", score1.score);
 
    return 0;
}

0 人点赞