27.C语言面向对象(上)

  • 学习人数 15K+
  • 适合有C语言基础人群学习
avatar
林耿亮

你好编程主讲老师

在之前的章节当中,我们在编写程序时,通常采用以下步骤:

  1. 将问题的解法分解成若干步骤
  2. 使用函数分别实现这些步骤
  3. 依次调用这些函数

这种编程风格的被称作面向过程。除了面向过程之外,还有一种被称作面向对象的编程风格被广泛使用。面向对象采用基于对象的概念建立模型,对现实世界进行模拟,从而完成对问题的解决。

C语言的语法并不直接支持面向对象风格的编程。但是,我们可以通过额外的代码,让C语言实现一些面向对象特性。在这一节当中,我们将探究什么是面向对象,以及怎样用C语言来实现它。

单纯理论上的讨论可能比较难以理解,为了能够让我们的讨论能够落地到实际中,我们选取学校为场景,展开对面向对象风格编程的讨论。

一般而言面向对象风格的编程具有以下3大特性:

  • 封装
  • 继承
  • 多态

我们将以这3个特性为线索,讨论C语言如何面向对象编程。

1. 封装

我们来看看学校里面最重要的主体是什么?是学生。学生肯定拥有很多属性,比如学生的学号、姓名、性别、考试分数等等。自然地,我们会声明一个结构体用于表示学生。

struct student {
    int id;         //  学号
    char name[20];  //  姓名
    int gender;     //  性别
    int mark;       //  成绩
};

学生的学号由入学年份班级序号拼接构成。

例如,某一个同学的是2022年入学的123班的26号学生。那么,它的学号为202212326

为了方便设置学号,我们有一个makeStudentId函数,参数为入学年份班级序号,它将这些数据拼接成字符串,再将字符串转换为整型数据,最后将这个整型数据作为学生的id并返回。

int makeStudentId(int year, int classNum, int serialNum)
{
    char buffer[20];
    sprintf(buffer, "%d%d%d", year, classNum, serialNum);
    int id = atoi(buffer);
    return id;
}

sprintf函数在第21节课《让熊跑起来》中有讲过,它和printf函数类似,printf函数会将占位符"%d%d%d"替换为其后的参数,将结果打印到控制台上。而sprintf不会将结果打印在控制台上,而是将结果存放在第一个参数buffer所指示的字符数组当中。

函数atoi能将buffer指示的字符串转换为整型并返回结果。

性别在结构体中存储为整型数值,0代表女生、1代表男生。而显示时,我们希望0显示为1显示为。因此,还需要有一对用于操作性别的函数。在函数命名中,使用numGender代表使用整型表示的性别。strGender代表使用字符串表示的性别。

我们将定义两个函数:

numGenderToStrGender表示,将整型表示的性别转换为字符串表示的性别strGenderToNumGender表示,将字符串表示的性别转换为整型表示的性别

const char *numGenderToStrGender(int numGender)
{
    if (numGender == 0)
    {
        return "女";
    }
    else if (numGender == 1)
    {
        return "男";
    }
    return "未知";
}

int strGenderToNumGender(const char* strGender)
{
    int numGender;
    if (strcmp("男", strGender) == 0)
    {
        numGender = 1;
    } 
    else if (strcmp("女", strGender) == 0)
    {
        numGender = 0;
    }
    else
    {
        numGender = -1;
    }
    return numGender;
}

我们将使用以下方式,调用这个结构体和这3个函数。

int main()
{
    struct student stu;

    //  设置数值
    //  学号:202212326
    //  姓名:小明
    //  性别: 男
    //  成绩:98
    stu.id = makeStudentId(2022, 123, 26);
    strcpy(stu.name, "小明");
    stu.gender = strGenderToNumGender("男");
    stu.mark = 98;

    //  打印这些数值
    printf("学号:%d\n", stu.id);
    printf("姓名:%s\n", stu.name);
    const char* gender = numGenderToStrGender(stu.gender);
    printf("性别:%s\n", gender);
    printf("分数:%d\n", stu.mark);

    return 0;
}

输出学生信息