C 语言 之 面向对象(一)

C 语言 之 面向对象(一)

了解C语言面向对象之前首先需要对C语言的指针、结构体有基本了解。

指针

正常使用数组:

void hello(){
    #define count 10
    // sh
    int a[count] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, a[i]);
    }
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, a[i]);
    }
    printf("================================\n");
    int *b = malloc(sizeof(int) * 10);
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, b[i]);
    }
    free(b);
    b = malloc(sizeof(int) * 10);
    b[1] = 44;
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, b[i]);
    }
    free(b);
}

数组默认是个指针常量,无法修改指针指向,但可以修改内容

指针常量

void hello(){
    #define count 10
    // sh
    int a[count] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, a[i]);
    }
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, a[i]);
    }
    printf("================================\n");
    int * const b = malloc(sizeof(int) * 10); // 定义指针常量
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, b[i]);
    }
    // free(b);
    // b = malloc(sizeof(int) * 10); 
    b[1] = 44;
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, b[i]);
    }
    free(b);
}

指针常量const在指针名称之前,意味着指针指向不可修改

常量指针


// 【关键补充】4. Person_SetAge函数的实现(之前缺失的部分)
void Person_SetAge(Person* self, int new_age) {
    if (self == NULL) return;  // 避免空指针访问
    // 可选:添加参数校验(如年龄不能为负数)
    if (new_age >= 0) {
        self->age = new_age;  // 修改结构体的age成员
    } else {
        printf("Invalid age: %d (must be non-negative)\n", new_age);
    }
}

void hello(){
    #define count 10
    // sh
    int a[count] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, a[i]);
    }
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, a[i]);
    }
    printf("================================\n");
    // const int * b = malloc(sizeof(int) * 10); // 定义常量指针 or
    int const * b = malloc(sizeof(int) * 10); // 定义常量指针
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, b[i]);
    }
    free(b);
    b = malloc(sizeof(int) * 10); 
    // b[1] = 44;
    for(int i = 0; i < count; i ++ ){
        printf("i: %d, value: %d\n", i, b[i]);
    }
    free(b);
}

常量指针意味着值是无法被修改的,但是你可以直接换新值。

结构体

定义结构体

// 定义结构体类型:struct Student
struct Student {
    char name[20];  // 姓名(字符数组)
    int age;        // 年龄(整数)
    float score;    // 成绩(浮点数)
};

使用结构体1

void hello(){
    struct Student stu1, stu2;
    struct Student stu3 = {
        "zsh",
        18,
        95.5F
    };
    struct Student stu4 = {
        .age = 19,
        .name = "zsh1",
        .score = 96.5F
    };
    printf("name: %s, age: %d, score: %f\n", stu1.name, stu1.age, stu1.score);
    printf("name: %s, age: %d, score: %f\n", stu2.name, stu2.age, stu2.score);
    printf("name: %s, age: %d, score: %f\n", stu3.name, stu3.age, stu3.score);
    printf("name: %s, age: %d, score: %f\n", stu4.name, stu4.age, stu4.score);
}

使用结构体2

void hello(){
    struct Student *stu1 = malloc(sizeof(struct Student));
    stu1->name = "zsh";
    stu1->age = 17;
    stu1->score = 95.5F;
    printf("name: %s, age: %d, score: %f\n", stu1 -> name, stu1 -> age, stu1 -> score);
    free(stu1);
	stu1 = NULL;
}

结构体2

使用别名

// 定义结构体类型:struct Student
typedef struct Student {
    char *name;  // 姓名(字符数组)
    int age;        // 年龄(整数)
    float score;    // 成绩(浮点数)
} Student;
// or
typedef struct Student Student;
// 定义结构体类型:struct Student
struct Student {
    char *name;  // 姓名(字符数组)
    int age;        // 年龄(整数)
    float score;    // 成绩(浮点数)
};

简化调用

void hello(){
    Student *stu1 = malloc(sizeof(Student));
    stu1->name = "zsh";
    stu1->age = 17;
    stu1->score = 95.5F;
    free(stu1);
    printf("name: %s, age: %d, score: %f\n", stu1 -> name, stu1 -> age, stu1 -> score);
}

给结构体定义方法

定义结构体

#ifndef LEARNC01_H
#define LEARNC01_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义类型别名
typedef struct Student Student;
// 定义方法别名
/**
 * 方法别名类型toStringFunc,参数void,返回值void
 */
typedef void (*ToStringFunc)(Student*);

// 定义结构体类型:struct Student
struct Student {
    char *name;  // 姓名(字符数组)
    int age;        // 年龄(整数)
    float score;    // 成绩(浮点数)
    ToStringFunc toString;
};

// 定义方法
/**
 * 创建对象
 */
Student* StudentCreate(const char *name, const int age, const float score);
void StudentPrint(Student* self);
void StudentDestroy(Student* self);

void hello();

#endif // LEARNC01_H

源文件

// ==================
Student* StudentCreate(const char* name, const int age, const float score){
    Student* self = malloc(sizeof(Student));
    if (self == NULL){
        printf("内存不足\n");
        return NULL;
    }
    const int nameLength = strlen(name);
    self->name = malloc(nameLength);
    strcpy(self -> name, name);
    printf("name: %s, nameLength: %d, self->name: %s, self->nameLength: %d\n", name, nameLength, self->name, strlen(self->name));
    self->age = age;
    self -> score = score;
    self->toString = StudentPrint; // 引用头文件方法别名,链接时指向实现方法
    return self;
}
void StudentDestroy(Student *self){
    if (self == NULL) return;
    free(self->name);  // 先释放姓名的堆内存
    free(self);     
}

void StudentPrint(Student* self) {
    printf("Student(name=%s, age=%d, score=%f)", self->name, self->age, self->score);
}

void hello(){
    Student *student = StudentCreate("zsh", 18, 95.5F);
    if(student == NULL){
        printf("student == NULL\n");
        return;
    }
    student->toString(student);
    StudentDestroy(student);
}

多态TODO

头文件

#ifndef LEARNC01_H
#define LEARNC01_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 1. 基类
typedef struct Person Person;
// 基类方法
typedef void (*ToStringFunc)(Person*);
typedef void (*DestroyFunc)(Person*);
// 基类结构体
struct Person {
    char *name;
    int age;
    ToStringFunc toString;
    DestroyFunc destroy;
};

// 2. 定义派生类类型别名
typedef struct Student Student;

// 定义结构体类型:struct Student
struct Student {
    Person parent;
    float score;    // 成绩(浮点数)
    char *school;
};

// 3. 定义派生类类型别名
typedef struct Teacher Teacher;

struct Teacher {
    Person parent;
    char *education;
    char *school;
};

// 定义方法
/**
 * 创建 Student 对象方法
 */
Student* StudentCreate(const char *name, const int age, const float score, const char *school);
static void StudentToString(Person *person);
static void StudentDestroy(Person *person);

/**
 * 创建 Teacher 对象方法
 */
Teacher* TeacherCreate(const char *name, const int age, const char *education, const char *school);
static void TeacherDestroy(Person *person);
static void TeacherToString(Person *person);

/**
 * 多态方法
 */
void printPersonInfo(Person *person);

void hello();

#endif // LEARNC01_H

源文件

#include "learnc01.h"

// ========= Student =========
Student* StudentCreate(const char* name, const int age, const float score, const char *school){
    Student* self = malloc(sizeof(Student));
    if (self == NULL){
        printf("内存不足\n");
        return NULL;
    }
    self->parent.toString = StudentToString;
    self->parent.destroy = StudentDestroy;
    const int nameLength = strlen(name);
    self->parent.name = malloc(nameLength);
    strcpy(self->parent.name, name);
    self->parent.age = age;
    self->score = score;
    const int schoolLength = strlen(school);
    self->school = malloc(schoolLength);
    strcpy(self->school, school);
    printf("构造函数 -> Student(name=%s, age=%d, score=%f, school=%s)\n", self->parent.name, self->parent.age, self->score, self->school);
    return self;
}
static void StudentToString(Person *person){
    Student *student = (Student*) person;
    // student.
    printf("Student(name=%s, age=%d, score=%f, school=%s)\n", student->parent.name, student->parent.age, student->score, student->school);
}
static void StudentDestroy(Person *person){
    Student *student = (Student*) person;
    free(student->parent.name);
    free(student->school);
    free(student);
}

// ========= Teacher =========
Teacher* TeacherCreate(const char *name, const int age, const char *education, const char *school){
    Teacher *self = malloc(sizeof(Teacher));
    if(self == NULL){
        printf("Teacher 内存不足\n");
        return NULL;
    }

    self->parent.toString = TeacherToString;
    self->parent.destroy = TeacherDestroy;

    const int nameLength = strlen(name) + 1;
    self->parent.name = malloc(nameLength);
    strcpy(self->parent.name, name);
    self->parent.age = age;

    const int educationLength = strlen(education) + 1; // 带上 \0 空字符
    self->education = malloc(educationLength);
    strcpy(self->education, education);

    const int schoolLength = strlen(school) + 1;
    self->school = malloc(schoolLength);
    strcpy(self->school, school);

    printf("构造函数 Teacher(name=%s, age=%d, education=%s, school=%s, nameLength=%d)\n", self->parent.name, self->parent.age, self->education, self->school, nameLength);

    return self;
}
static void TeacherToString(Person *person){
    Teacher *teacher = (Teacher*) person;
    printf("Teacher(name=%s, age=%d, education=%s, school=%s)\n", teacher->parent.name, teacher->parent.age, teacher->education, teacher->school);
}
static void TeacherDestroy(Person *person){
    Teacher *teacher = (Teacher*) person;
    free(teacher->parent.name);
    free(teacher->school);
    free(teacher->education);
    free(teacher);
}

/**
 * 多态方法
 */
void printPersonInfo(Person *person){
    if(person == NULL){
        printf("person == NULL\n");
        return;
    }
    person->toString(person);
}

void hello(){
    Person *student = (Person*)StudentCreate("s_zsh", 18, 95.5, "tyut");
    Person *teacher = (Person*)TeacherCreate("t_zsh", 18, "本科", "tyut");
    printPersonInfo(teacher);
    printPersonInfo(student);
    student->destroy(student);
    teacher->destroy(teacher);
}
posted @ 2025-09-17 22:39  爱情丶眨眼而去  阅读(5)  评论(0)    收藏  举报