说实话,C/C++程序员面试如果只让我押一道必考题,struct和class的区别绝对排得进前三。这道题看着基础,却特别能筛人:它能同时考你对C语言底层内存布局的理解、对C++面向对象语法演进的认识,还能顺带摸清你有没有真正写过工程代码,而不是只会背八股。很多候选人上来就答“struct默认public,class默认private”,然后戛然而止,这种回答在面试官眼里基本等于没答。今天这篇就把这道题彻底聊透,从C语言里struct的原始定位,到C++里class的语法扩张,再到面试官最爱追问的内存对齐、POD、继承权限这些细节,一次讲清楚。
如果你正在准备C/C++开发岗面试,或者写了好几年C想转C++,又或者纯粹想搞明白“这两个东西到底差在哪”——这篇文章就是给你写的。我会把底层原理、代码演示、面试答题思路全部拆开揉碎,尽量做到看完就能用。
1. 内容整体设计与思路拆解
1.1 为什么面试官爱考这道题
这道题之所以高频,是因为它横跨C和C++两门语言,直接考察你对“面向过程”和“面向对象”两种编程范式的理解。一个候选人如果只背过语法差异,却说不清C语言为什么没有class、C++为什么又要保留struct,那说明他对语言设计缺少整体感知。
从实际工作场景看,很多嵌入式项目是C和C++混编的,代码里既有纯C的struct,也有C++的class。如果你不清楚两者的边界,很容易写出“看似是C++其实是C”的代码,或者反过来在这种混编环境里埋下坑。所以面试官问这道题,本质上是想确认你有没有处理过真实工程项目,而不只是刷过题库。
1.2 我决定从“C语言视角”切入的原因
网上绝大多数帖子讲这道题,都是上来就对比C++的struct和class,默认你已经把C语言那部分吃透了。但我在实际面试中发现,恰恰是C语言的struct部分最容易翻车——很多人不知道C语言里struct压根不能直接定义空结构体,不知道struct不能包含成员函数但可以用函数指针模拟,不知道typedef struct的两种写法有什么区别。
所以这篇文章我走一条稍微“反套路”的路线:先把C语言里的struct彻底讲透,再过渡到C++的struct和class对比。这样你不仅能答清“class和struct的区别”,还能顺带答清“C的struct和C++的struct区别”,这是很多候选人完全没准备过的角度,答出来就是加分项。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. C语言中struct的核心定位与实战细节
2.1 数据聚合体:struct最原始的使命
C语言里的struct,本质上就是一组变量的打包。它没有成员函数、没有访问控制、没有继承,也没有多态。你在struct里只能放数据成员,而且这些数据成员是“裸”的——外部代码可以直接访问,没有任何封装和保护机制。
c复制#include <stdio.h>
#include <string.h>
struct Student {
char name[32];
int age;
float score;
};
int main() {
struct Student s1;
// 直接操作成员,没有任何访问限制
strcpy(s1.name, "Tom");
s1.age = 20;
s1.score = 88.5;
printf("%s %d %.1f\n", s1.name, s1.age, s1.score);
return 0;
}
这段代码放到C语言里完全合法,s1.age可以直接读写。但如果你试图在struct里定义一个函数成员,比如:
c复制struct Student {
char name[32];
int age;
// 错误!C语言的struct不能包含函数
void printInfo() { }
};
编译会直接报错。C语言的struct就是纯粹的数据容器,它不承载任何逻辑。这一点是理解整个问题的基石:C语言里没有面向对象,所以struct只能是“数据的集合”。
2.2 C语言中用struct实现“伪面向对象”
那问题来了:C语言的项目比如Linux内核、嵌入式驱动里,经常能看到看起来很像“对象”的写法,这是怎么做到的?答案是函数指针。
c复制struct Animal {
char name[32];
void (*speak)(struct Animal *self); // 函数指针成员
};
void dogSpeak(struct Animal *self) {
printf("%s: 汪汪\n", self->name);
}
void catSpeak(struct Animal *self) {
printf("%s: 喵喵\n", self->name);
}
int main() {
struct Animal dog;
strcpy(dog.name, "旺财");
dog.speak = dogSpeak;
struct Animal cat;
strcpy(cat.name, "咪咪");
cat.speak = catSpeak;
dog.speak(&dog);
cat.speak(&cat);
return 0;
}
这段代码在C语言
