ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

一、基础语法、数据类型与函数

一、基础语法、数据类型与函数 一、基础语法、数据类型与函数共33项1.C/C中程序的开发流程2.C/C中面向对象和面向过程的区别3.声明和定义的区别是什么4.i和i哪个执行效率高5.数组名是什么6.C中小数用二进制如何表示7.C里有那些类型转换运算符8.C中赋值与初始化的区别9.宏函数和自定义函数的区别10.函数调用的步骤11.C定义常量两种方式是什么12.介绍一下C/C各自的特点13.介绍一下const用途14.C函数中值的传递方式有哪几种15.C里面是不是所有的动作都是main()引起的16.介绍一下左值和右值引用17.介绍一下C转型操作符18.const、constexpr、consteval、constinit有什么区别19.C/C中野指针的概念20.C/C中指针和引用的区别21.什么是指针数组、什么是数组指针22.指针与数组的区别23.引用和指针的区别24.什么是内联函数25.函数重载条件26.构造函数的特点27.什么是析构函数、析构函数的作用28.空指针和悬空指针的区别29.介绍一下static数据成员和static成员函数30.如何引用一个已经定义过的全局变量31.全局变量和局部变量有什么区别怎么实现的操作系统和编译器是怎么知道的32.static全局变量与普通的全局变量有什么区别static局部变量和普通局部变量有什么区别static函数与普通函数有什么区别33.对于一个频繁使用的短小函数在C语言中应用什么实现在C中应用什么实现C/C 基础语法 · 数据类型与函数 — 知识图谱这 33 道题是 C/C 面试题中最基础、最密集的一块涵盖编译流程、语法机制、类型系统、函数语义、指针引用、面向对象、const/static 体系。它们之间的联系可以概括为一条主线从源代码到可执行文件的过程中编译器和运行时如何理解“名字、类型、作用域、生命周期、值类别”这些概念。一、33 道题的归类与联系主题层对应题号核心问题编译与构建1、3、15代码怎么变成可执行文件声明和定义为什么分开编程范式2、12C 与 C 的本质区别面向过程 vs 面向对象类型系统6、7、8、13、17、18、16类型怎么表示、怎么转换、const 体系、值类别函数机制9、10、14、24、25、33函数怎么调用、怎么传递、怎么优化、怎么重载指针与引用5、19、20、21、22、23、28数组名、指针、引用、各种危险指针面向对象基础26、27、29构造、析构、static 成员作用域与生命周期4、11、30、31、32变量存在哪里、什么时候创建销毁、static 的作用二、逐层拆解联系1. 编译与构建一切语法的起点第 1 题开发流程、第 3 题声明与定义、第 15 题是否所有动作都由 main 引起是地基。C/C 程序从源代码到可执行文件经历源代码 (.c/.cpp) ↓ 预处理 (Preprocessor)宏替换、头文件展开、条件编译 ↓ 编译 (Compiler)词法/语法/语义分析生成汇编 ↓ 汇编 (Assembler)汇编转机器码生成目标文件 (.o/.obj) ↓ 链接 (Linker)符号解析、重定位生成可执行文件声明 vs 定义声明告诉编译器“这个名字存在、类型是什么”定义创建实际的对象或函数体。一个实体可以被声明多次但只能定义一次ODROne Definition Rule。为什么需要分开声明支持模块化编译头文件放声明源文件放定义减少编译依赖。main 不是一切的起点main是程序入口但在此之前会执行运行时启动代码如全局对象构造、初始化静态对象、__libc_start_main之后还可以通过atexit注册清理函数。联系理解了编译流程才能理解为什么头文件不能重复定义、为什么extern可以引用全局变量、为什么链接会报 undefined reference。2. 编程范式C 与 C 的本质分野第 2 题面向对象 vs 面向过程、第 12 题C/C 各自特点。特性CC范式面向过程多范式面向对象、泛型、过程式核心抽象函数 数据结构类 对象 模板内存管理malloc/free 手动new/delete 智能指针/RAII封装/继承/多态无有函数重载/默认参数/引用无有模板无有与 C 兼容自身基本兼容 C联系C 不是“带类的 C”而是在 C 的基础上增加了抽象机制。很多 C 特性引用、函数重载、默认参数本质上是为了让面向对象和泛型编程更安全、更自然。3. 类型系统值的本质与约束第 6、7、8、13、16、17、18 题。小数二进制表示第 6 题浮点数按 IEEE 754 存储由符号位、指数位、尾数位组成。因为二进制无法精确表示某些十进制小数如 0.1所以浮点数比较不能直接用。类型转换运算符第 7、17 题C 风格(type)exprC 风格static_cast、dynamic_cast、const_cast、reinterpret_cast为什么需要分开static_cast编译期检查、dynamic_cast运行时类型检查、const_cast去除 const、reinterpret_cast低层比特重新解释。赋值 vs 初始化第 8 题初始化是对象创建时赋予初值赋值是对象已存在后修改值。对类类型初始化调用构造函数赋值调用operator。const 体系第 13、18 题const运行时常量保证不可修改。constexpr编译期常量可用于数组大小、模板参数。consteval强制编译期求值C20。constinit强制静态/线程局部变量用常量初始化避免静态初始化顺序问题C20。左值与右值引用第 16 题左值有名字、可取地址、可持久存在的对象。右值临时对象、即将销毁的值。右值引用T用于移动语义和完美转发避免不必要的拷贝。联系类型系统回答“一个值是什么、能做什么、怎么转换、生命周期多久”。const 体系和值类别是现代 C 性能优化移动语义和类型安全的核心。4. 函数机制调用、传递、优化、重载第 9、10、14、24、25、33 题。函数调用步骤第 10 题保存调用者上下文寄存器、返回地址。参数压栈或放入寄存器。跳转被调用函数。创建被调用函数栈帧分配局部变量。执行函数体。返回值传递。恢复调用者上下文跳转返回。参数传递方式第 14 题值传递拷贝实参。指针传递传递地址可修改原对象。引用传递别名无拷贝可修改或 const 保护。右值引用传递用于移动语义接管资源。内联函数第 24、33 题用inline建议编译器在调用点展开函数体减少函数调用开销。C 用宏函数也能实现类似效果但宏无类型检查、无作用域、副作用难控C 推荐用内联函数替代宏。函数重载第 25 题同一作用域内同名函数参数列表不同类型、个数、顺序。C 通过 Name Mangling 实现编译器生成不同符号名。宏函数 vs 自定义函数第 9、33 题特性宏函数自定义函数 / 内联函数处理阶段预处理期编译期类型检查无有作用域/调试无作用域难调试有作用域可调试副作用参数可能多次求值参数只求值一次适用条件编译、日志行号通用计算、频繁调用短函数联系函数是程序的基本执行单元。理解调用过程、传递方式、内联优化、重载机制才能写出高效且正确的 C 代码。5. 指针与引用C/C 的灵魂与陷阱第 5、19、20、21、22、23、28 题。数组名第 5 题大多数情况下数组名会退化为指向首元素的指针但sizeof(arr)、取地址arr、用数组引用初始化时不是指针。指针与引用区别第 20、23 题特性指针引用是否可为空可以nullptr不能必须初始化是否可重新绑定可以不能绑定后不可改语法需要解引用*p直接使用sizeof指针大小被引用对象大小本质独立变量存地址别名编译器实现通常也是指针指针数组 vs 数组指针第 21 题int *arr[10]指针数组10 个int*。int (*arr)[10]数组指针指向int[10]的指针。指针与数组区别第 22 题数组是一块连续内存有大小信息指针是地址变量。数组名在表达式中常退化为指针但数组本身不是指针。野指针、空指针、悬空指针第 19、28 题空指针nullptr指向无效地址访问会崩溃。野指针未初始化或越界的指针行为不可预测。悬空指针指向已释放或已超出作用域的内存。联系指针是 C/C 直接操作内存的工具引用是 C 为了更安全、更自然的语法而提供的别名机制。它们共同支撑了参数传递、动态内存、容器迭代器等核心功能。6. 面向对象基础构造、析构、static第 26、27、29 题。构造函数第 26 题与类同名、无返回值、可重载、可默认/参数化/拷贝/移动构造。负责对象初始化。析构函数第 27 题~ClassName()无参数、无返回值、不可重载。负责资源清理是 RAII 的基石。static 数据成员和成员函数第 29 题static数据成员属于类不属于某个对象所有对象共享。static成员函数没有this指针只能访问 static 成员和全局变量。联系构造和析构定义了对象的生命周期边界static 成员则跨越对象生命周期存在。它们共同支撑了 C 的资源管理和类级状态。7. 作用域与生命周期变量在哪里、存在多久第 4、11、30、31、32 题。i vs i 效率第 4 题对内置类型现代编译器优化后通常无差别。对自定义类型迭代器i返回自身引用i返回旧值副本所以i更高效。C 中推荐前置自增。定义常量两种方式第 11 题#define PI 3.14宏常量预处理替换无类型。const double PI 3.14;类型安全有作用域推荐。C11 后还可以用constexpr。引用已定义全局变量第 30 题用extern声明告诉编译器该变量在其他地方定义。全局变量 vs 局部变量第 31 题全局变量定义在所有函数外存储在数据段/BSS程序启动到结束存在。局部变量定义在函数或块内存储在栈进入作用域创建离开销毁。编译器通过作用域规则识别操作系统通过进程内存布局管理。static 全局 / static 局部 / static 函数第 32 题static全局变量只在当前翻译单元可见避免命名冲突。static局部变量只在函数内可见但生命周期贯穿程序只初始化一次。static函数只在当前翻译单元可见内部链接。联系作用域决定“谁能看见”生命周期决定“存在多久”链接属性决定“谁能链接”。static 同时影响这三个维度是 C/C 中多义但强大的关键字。三、对基础语法、数据类型与函数的整体理解建议按这条主线建立认知程序是编译出来的预处理 → 编译 → 汇编 → 链接。声明和定义分离是为了支持模块化。C 是面向过程的C 是多范式的C 在 C 基础上增加了类、引用、重载、模板、异常等抽象。类型系统约束值的行为理解转换、const、左值右值才能写出类型安全和高效的代码。函数是执行单元调用有成本传递有语义内联和重载是优化和抽象手段。指针和引用是内存的钥匙指针灵活但危险引用安全但受限。对象有生命周期构造函数创建析构函数销毁static 跨越对象存在。作用域、生命周期、链接属性是变量的三重属性static 同时修改这三者。四、记忆口诀预处理编译汇编链接声明定义要分清C 过程 C 多范式类引重载模板行const constexpr 编译期左值右值移动轻值传指针引用传内联替代宏函数数组名退化为指针sizeof 和 arr 除外指针数组 int* arr[]数组指针 int (*arr)[]构造函数始析构函数终static 成员类级同全局局部看作用域static 三义要记清。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进