最近在帮几个准备校招的朋友做C语言面试复盘,发现一个特别有意思的现象:十份简历里至少有八份写了"熟悉C/C++",但真到面试官问一句"struct和class到底有什么区别",很多人就卡住了。有的能答上"class默认private,struct默认public",再深一层就开始含糊。这个问题看起来基础,实际上能挖出你对C语言内存模型、C++对象模型、访问控制、甚至是POD类型理解得扎不扎实。我把这些年积累的面试经验和实际项目里踩过的坑梳理了一下,希望能帮你把这条线彻底理清楚。
这篇文章适合三类人:正在准备C/C++岗位面试的应届生、从C转C++但一直没细想过这个区别的开发、以及需要用C语言做嵌入式或系统级开发的朋友。我会从两种语言的设计初衷讲起,再落到代码层面的细节对比,最后结合真实项目讲讲struct和class该怎么选、怎么用不出问题。
1. 从一道高频面试题说起:struct在C和C++里的定位差异
1.1 为什么面试官爱问这道题
这道题之所以高频,是因为它像一面照妖镜,能快速筛掉"背了八股文但没写过项目"的人。
面试官问"struct和class的区别",表面考的是语法,实际考的是三件事:第一,你有没有真正理解C语言中struct的原始设计意图——它就是一个"数据的容器",不携带行为。第二,你能不能说清楚C++引入class之后,struct这个关键字为什么被保留下来,以及保留之后它和class在语言层面到底被拉近了多大距离。第三,你能否把"默认访问权限"这种零散知识点,串成对"封装、继承、多态"三大面向对象特性的整体理解。
我见过一个很典型的回答:候选人说"struct是C语言的,class是C++的,class能继承,struct不能"。这个回答错了一半。struct在C++里完全可以继承,甚至可以实现多态。如果你的认知还停留在"struct只是C的遗留物",那面试官基本可以判断你对C++对象模型没有系统学习过。
1.2 C语言里struct的本质:它只是内存布局的说明书
在纯C语言环境里,struct的核心作用非常朴素:把若干个不同类型的变量打包成一个整体,方便统一管理和传递。
从底层看,struct定义的是"内存布局规则"。比如:
c复制struct Point {
int x;
int y;
};
这个定义告诉编译器:Point类型占用8个字节(在int为4字节的平台上),x在偏移0处,y在偏移4处。它不包含任何函数指针,不包含任何方法,也没有构造函数和析构函数的概念。
C语言中,struct只能用来声明数据成员。如果你想对它进行"操作",只能在外部写函数,比如:
c复制struct Point* point_create(int x, int y);
void point_print(struct Point* p);
这就是C语言面向过程编程的典型风格:数据与操作分离。数据是struct,操作是函数,函数通过指针拿到数据再加工。这种设计在Linux内核代码里极其常见,比如struct file_operations就是一堆函数指针的集合,本质上是"用struct模拟面向对象的接口"。
有个细节特别值得注意:C语言里,struct类型名前必须带struct关键字,除非你用typedef给它起一个别名。这也是面试里经常出现的陷阱题:
c复制typedef struct Node {
int data;
struct Node* next;
} Node;
这里struct Node* next不能写成Node* next,因为typedef别名在结构体内部定义结束前还不生效。这个细节很基础,但真的有很多人在笔试里栽过。
我们再补一个热搜词相关的问题:"怎么知道struct中的成员大小"。这个问题的本质其实是在问内存对齐。C语言里求某个成员相对于结构体首地址的偏移量,惯用写法是:
c复制#include <stddef.h>
offsetof(struct Point, y);
求整个结构体大小用sizeof(struct Point),但注意sizeof的结果会受到对齐规则影响。比如:
c复制struct A {
char c; // 偏移0
int i; // 偏移4,不是偏移1,因为int需要4字节对齐
};
这个结构体在x86-64平台上通常占用8字节,而不是5字节。面试官问"struct成员大小",实际上是在考察你对内存对齐、填充字节(padding)的理解。这个问题我很建议你亲手写代码验证一下,因为单纯背结论很容易忘记。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. C++为什么还保留struct:它与class的同与不同
2.1 默认访问权限:public和private是第一个分水岭
当我们进入C++,核心事实是:struct和class在功能上几乎完全等价。它们都可以有成员函数、构造函数、析构函数、静态成员、运算符重载,甚至都可以作为基类被继承。
唯一的语言层面的区别,就是默认访问权限:
struct默认成员是public- `cl
