Public C语言是什么?为何用public修饰?

99ANYc3cd6
预计阅读时长 21 分钟
位置: 首页 C语言 正文

这是一个非常核心且容易混淆的概念,因为它涉及到 C 语言的两种主要编程风格:结构化编程面向对象编程

public c 语言
(图片来源网络,侵删)

核心结论先行

标准 C 语言 中,没有 public 关键字

public 是一个访问修饰符,主要用于 面向对象编程,例如在 C++、Java、C# 等语言中,用来控制类成员(变量和方法)的可见性,表示它们是“公有的”,可以在任何地方被访问。

C 语言本身不是一门纯粹的面向对象语言,它没有类、继承等内置的 OOP 特性,C 语言可以通过一些特殊的技巧和约定来模拟出类似 publicprivate 的访问控制,尤其是在开发大型库或框架时。

下面我们分两部分来详细解释:

public c 语言
(图片来源网络,侵删)

第一部分:为什么标准 C 没有 public

C 语言的设计哲学是简洁、高效、贴近硬件,它通过 struct(结构体)来组织数据,通过函数来操作数据,这种风格被称为结构化编程过程化编程

在 C 语言中,一个 struct 默认情况下,其所有成员都是“公开”的,你可以直接创建一个结构体变量,然后通过点号 访问它的任何一个成员。

示例:标准的 C 结构体

#include <stdio.h>
#include <string.h>
// 定义一个“学生”结构体
struct Student {
    int id;         // 学号
    char name[50];  // 姓名
    float score;    // 分数
};
int main() {
    // 创建一个学生变量
    struct Student stu1;
    // 直接访问和修改结构体的成员(这就是“公开”的体现)
    stu1.id = 101;
    strcpy(stu1.name, "张三");
    stu1.score = 95.5f;
    // 直接读取成员
    printf("学生ID: %d\n", stu1.id);
    printf("学生姓名: %s\n", stu1.name);
    printf("学生分数: %.2f\n", stu1.score);
    return 0;
}

在上面的代码中,Student 结构体的所有成员 id, name, score 都可以被外部代码直接访问和修改,这就是 C 语言默认的行为,它没有 public 关键字来声明这些成员是“公有的”,因为它们天生就是公有的。

public c 语言
(图片来源网络,侵删)

第二部分:如何在 C 中模拟 publicprivate

虽然 C 语言没有 public,但在实际开发中,我们常常希望隐藏一个结构体的内部实现细节,只暴露必要的接口,以防止外部代码误操作,这被称为信息隐藏数据封装,这是面向对象编程中的一个重要原则。

模拟 publicprivate 的常用方法是 不透明指针句柄

模拟方法:不透明指针

这种方法的核心思想是:

  1. private 部分:将结构体的真正定义放在一个 .c 文件中(源文件),而不是 .h 文件(头文件)。
  2. public 部分:在头文件中,只声明一个指向该结构体的指针(struct MyStruct*),不透露其内部成员。
  3. public 接口:提供一组公共的函数(以 mystruct_ 开头,作为命名空间),这些函数接收不透明指针作为参数,并在 .c 文件内部实现对结构体成员的操作。

这样,外部代码只能通过你提供的公共函数来操作数据,而无法直接访问和修改结构体内部,从而实现了封装。

示例:模拟封装的“学生”管理

student.h (公共接口头文件) 这个文件是给用户(其他程序员)看的,它只告诉用户“有什么功能可以用”,但隐藏了“这些功能是如何实现的”。

// student.h
#ifndef STUDENT_H
#define STUDENT_H
// 1. 前向声明,告诉编译器 "Student" 是一个结构体类型
//    但不透露它的内部成员,这就是 "private" 的核心。
struct Student;
// 2. 公共的构造函数 (模拟 public)
//    返回一个不透明指针,用户只能持有这个指针,但看不到内部。
struct Student* student_create(int id, const char* name, float score);
// 3. 公共的访问方法 (模拟 public)
//    用户只能通过这些函数来获取信息。
int student_get_id(const struct Student* s);
const char* student_get_name(const struct Student* s);
float student_get_score(const struct Student* s);
// 4. 公共的修改方法 (模拟 public)
//    用户只能通过这些函数来修改信息。
void student_set_score(struct Student* s, float new_score);
// 5. 公共的析构函数 (模拟 public)
void student_destroy(struct Student* s);
#endif // STUDENT_H

student.c (私有实现文件) 这个文件包含了结构体的真正定义和所有函数的具体实现,这是“私有的”部分。

// student.c
#include "student.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 6. 在这里定义结构体的真正成员 (private)
//    这个定义对外是不可见的。
struct Student {
    int id;
    char name[50];
    float score;
};
// 7. 实现公共函数
struct Student* student_create(int id, const char* name, float score) {
    struct Student* s = (struct Student*)malloc(sizeof(struct Student));
    if (s) {
        s->id = id;
        strncpy(s->name, name, sizeof(s->name) - 1);
        s->name[sizeof(s->name) - 1] = '\0'; // 确保字符串终止
        s->score = score;
    }
    return s;
}
int student_get_id(const struct Student* s) {
    return s->id;
}
const char* student_get_name(const struct Student* s) {
    return s->name;
}
float student_get_score(const struct Student* s) {
    return s->score;
}
void student_set_score(struct Student* s, float new_score) {
    if (s) {
        s->score = new_score;
    }
}
void student_destroy(struct Student* s) {
    if (s) {
        free(s);
    }
}

main.c (使用代码) 用户(其他程序员)只需要包含 student.h,并使用提供的公共函数即可,他无法直接操作 stu->idstu->score

// main.c
#include "student.h"
#include <stdio.h>
int main() {
    // 用户只能持有不透明指针,无法知道 Student 内部有什么
    struct Student* stu = student_create(101, "李四", 88.0f);
    // 只能通过公共函数访问数据
    printf("学生姓名: %s\n", student_get_name(stu));
    printf("学生分数: %.2f\n", student_get_score(stu));
    // 只能通过公共函数修改数据
    student_set_score(stu, 92.5f);
    printf("更新后分数: %.2f\n", student_get_score(stu));
    // 只能通过公共函数销毁对象
    student_destroy(stu);
    return 0;
}

总结这种模拟方法:

  • public:指 student.h 中声明的所有函数,以及不透明指针 struct Student* 本身(用户可以传递它)。
  • private:指 student.cstruct Student 的具体定义,包括它的所有成员变量。

通过这种方式,C 语言实现了与 OOP 中 publicprivate 类似的效果,极大地提高了代码的模块化程度和可维护性。


第三部分:C++ 中的 public

为了形成对比,我们简单看一下在 C++ 中 public 是如何工作的,C++ 是 C 的超集,它原生支持面向对象编程。

在 C++ 中,public 是一个访问控制说明符,用于类内部。

示例:C++ 中的 public

#include <iostream>
#include <string>
class Student { // C++ 使用 class 关键字
private: // private 成员只能在类的内部访问
    int id;
    std::string name;
    float score;
public: // public 成员可以在类的内部和外部访问
    // 构造函数
    Student(int i, const std::string& n, float s) : id(i), name(n), score(s) {}
    // 公共方法
    int getId() const { return id; }
    std::string getName() const { return name; }
    float getScore() const { return score; }
    void setScore(float newScore) { score = newScore; }
};
int main() {
    Student stu(101, "王五", 75.0f);
    // 可以通过公共方法访问数据
    std::cout << "学生姓名: " << stu.getName() << std::endl;
    // 不能直接访问私有成员,下面的代码会编译错误
    // stu.id = 102; // Error: 'int Student::id' is private
    return 0;
}
特性 标准 C 语言 C++ 语言
public 关键字 没有 ,是访问修饰符
封装实现方式 通过 不透明指针函数接口 手动模拟 语言内置的 public, private, protected 关键字
数据结构 struct(默认成员公开) struct(默认成员公开)和 class(默认成员私有)
核心思想 结构化/过程化编程 面向对象编程

当你在 C 语言的语境下看到“public”这个词时,可以确定它指的是一种编程技巧和设计模式,而不是语言本身的关键字,它的目的是为了在 C 的框架内实现数据封装和信息隐藏,以达到更好的代码组织。

-- 展开阅读全文 --
头像
织梦缩略图调用方法是什么?
« 上一篇 04-20
织梦列表顶踩数标签如何调用与显示?
下一篇 » 04-20

相关文章

取消
微信二维码
支付宝二维码

目录[+]