
目录一、C的工作场景1.大型系统软件开发2.音视频处理3.PC客户端开发4.服务端开发5.游戏引擎开发6.嵌入式开发7.机器学习引擎8.测试开发技术栈建议二、C书籍推荐C PrimerSTL源码剖析Effective C三、第一个C程序四、命名空间4.1 namespace的作用4.2 namespace的定义五、输入\输出六、缺省参数6.1 缺省参数的定义与特性6.2 缺省参数的使用规则6.3 注意事项七、函数重载八、引用8.1 引用的概念8.2 引用的特性8.3 引用的使用引用传参引用返回值引用与指针的区别8.4 const引用九、inline十、nullptr小编说一、C的工作场景C因其高性能、低资源消耗和跨平台特性被广泛应用于多个技术领域以下为具体分类及技术要点1.大型系统软件开发C常用于开发编译器如GCC、Clang、数据库如MySQL、MongoDB、操作系统如Windows内核、Linux部分模块及浏览器如Chrome渲染引擎。这类系统对执行效率和内存管理要求极高C的底层控制能力使其成为首选。2.音视频处理音视频领域的主流开源库FFmpeg、WebRTC、Mediasoup和播放器ijkplayer均基于C实现。开发需掌握音视频编解码H.264/265、AAC、流媒体协议RTMP、HLS及多线程优化技术。3.PC客户端开发Windows桌面应用如WPS、Adobe系列常采用C结合跨平台框架QT开发。QT提供图形界面组件支持快速构建跨平台应用兼顾性能与开发效率。4.服务端开发高性能后台服务游戏服务器、量化交易系统依赖C的高并发处理能力。关键技术包括网络编程epoll/IOCP、分布式架构及内存池优化对比Java更适合延迟敏感场景。5.游戏引擎开发主流引擎Unreal Engine、Cocos2d-x使用C实现核心渲染与物理模拟。开发者需掌握图形学OpenGL/DirectX、数据结构优化及引擎架构设计通常需阅读开源引擎源码深入学习。6.嵌入式开发分为应用层智能设备逻辑和驱动层硬件控制。典型场景包括智能家居摄像头、车载系统和物联网设备需熟悉RTOSFreeRTOS、ARM架构及低功耗优化。7.机器学习引擎底层计算库TensorFlow、PyTorch后端通过C加速矩阵运算和GPU计算。Python仅封装接口实际性能优化依赖C的SIMD指令和并行计算能力。8.测试开发自动化测试工具如Selenium插件和性能测试框架常用C编写高性能测试脚本尤其适合需要直接操作硬件的测试场景如嵌入式设备。技术栈建议基础必备掌握RAII、智能指针、STL容器及多线程std::thread。领域扩展根据方向学习特定库如QT for GUI、FFmpeg for音视频。性能优化熟练使用Profiler工具gperftools及缓存优化技巧。二、C书籍推荐C Primer作为C领域的经典语法书籍覆盖从基础到高级的语法特性。适合初学者预习但前期自学可能略显晦涩建议结合实践逐步消化。中后期可作为语法参考手册使用其系统性和全面性对查漏补缺尤为有效。STL源码剖析侯捷的经典著作通过逐层解析STL源码揭示底层实现原理。重点展示如何用C语法高效实现数据结构和算法涉及泛型编程、内存管理等高级技巧。建议在掌握基础语法和部分STL使用经验后阅读避免过早接触导致理解困难。Effective C侯捷翻译的进阶指南包含55条改善C编程的实践准则。书中内容涵盖资源管理、接口设计、性能优化等工程级技巧被誉为区分C程序员水平的分水岭作品。建议首次阅读安排在掌握核心语法后工作1-2年重读可深化对条款的理解。学习路径建议初期以《C Primer》为主框架建立语法体系配合实践项目消化基础概念中期结合《STL源码剖析》理解标准库设计思想培养源码阅读能力后期通过《Effective C》提升工程实践能力形成规范的编程习惯注意事项三本书籍存在明显的难度梯度不建议跳跃式阅读经典书籍需反复研读不同阶段会有新的收获建议每章节配合实际编码验证避免纯理论学习三、第一个C程序using namespace std; #include iostream int main() { cout hello world endl; return 0; }这里我们可能会看不懂接下来小编会一一讲解哦四、命名空间4.1 namespace的作用在C中很多变量、函数和后面学习到的类都是会大量存在的如果这些变量、函数都在全局域中必然会导致很多命名冲突。而命名空间的作用就是将这些变量、函数放到不同的命名空间域中实现本地化避免命名冲突的存在。4.2 namespace的定义/1.使用namespace 名称 {}定义里面可以有变量、函数、类其主要是和全局域独立可以定义同名变量等 int a 1; namespace Outer { int a 10; void func(); class b{}; //2.可以嵌套定义 namespace Outer_Outer { int b 10; } } //3.可以定义同名域编译器会自动合并 namespace Outer { int c 10; } int main() { //4.调用时优先调用全局域 cout a endl; //5.调用命名空间域时用 域名:: 调用 cout Outer::a endl; cout Outer::c endl; return 0; } //注意命名空间域只能在全局定义C中域有函数局部域全局域命名空间域类域域影响的是编译时语法查找⼀个变量/函数/类型出处(声明或定义)的逻辑所有有了域隔离名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑还会影响变量的⽣命周期命名空间域和类域不影响变量⽣命周期。其中C标准库都放在一个名为std的命名空间中。我们前面的using namespace std相当于将std的命名空间全部展开那么在接下来使用std里面的变量/函数时就不需要写std::了但是这仅适用于在写简短的代码和算法题时在工程中尽量不要使用。五、输入\输出iostream是标准输入输出流库。核心对象std::cin标准输入、std::cout标准输出、std::endl换行并刷新缓冲区。运算符 流插入输出 流提取输入这俩在 C 中是移位C 通过运算符重载赋予了新功能。优势自动识别类型支持自定义类型输入输出比 printf/scanf 更方便。#includeiostream using namespace std; int main() { // 在io需求⽐较⾼的地⽅如部分⼤量输⼊的竞赛题中加上以下3⾏代码 // 可以提⾼CIO效率 ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return 0; }六、缺省参数6.1 缺省参数的定义与特性缺省参数又称默认参数是在函数声明或定义时为形参指定的默认值。调用函数时若未传递对应实参则使用该默认值否则使用传递的实参值。缺省参数分为两种类型全缺省参数所有形参均指定默认值。半缺省参数仅部分形参指定默认值。6.2 缺省参数的使用规则半缺省参数的顺序要求半缺省参数必须从右向左依次连续指定默认值不可间隔或跳跃。例如void func(int a, int b 10, int c 20); // 正确从右向左连续缺省 void func(int a 5, int b, int c 20); // 错误非连续缺省函数调用的实参传递规则调用带缺省参数的函数时实参必须从左向右依次传递不可跳过中间参数。例如func(1); // 正确a1b和c使用默认值 func(1, 2); // 正确a1b2c使用默认值 func(1, , 3); // 错误不可跳过b直接传递c声明与定义的缺省参数分离规则若函数声明与定义分离缺省参数仅允许在声明中指定定义中不可重复。例如// 声明带缺省参数 void func(int a, int b 10); // 定义不可重复缺省参数 void func(int a, int b) { /* ... */ }6.3 注意事项缺省参数通常用于简化函数调用避免重复代码。缺省值必须是常量或全局变量不可为局部变量。默认参数在函数重载时需注意二义性问题。七、函数重载C支持在同⼀作用域中出现同名函数但是要求这些同名函数的形参不同可以是参数个数不同或者类型不同。这样C函数调用就表现出了多态行为使用更灵活。#includeiostream using namespace std; // 1、参数类型不同 int Add(int left, int right) { cout int Add(int left, int right) endl; return left right; } double Add(double left, double right) { cout double Add(double left, double right) endl; return left right; } // 2、参数个数不同 void f() { cout f() endl; } void f(int a) { cout f(int a) endl; } // 3、参数类型顺序不同 void f(int a, char b) { cout f(int a,char b) endl; } void f(char b, int a) { cout f(char b, int a) endl; } // 返回值不同不能作为重载条件因为调用时也无法区分 //void fxx() //{} // //int fxx() //{ // return 0; //} // 下面两个函数构成重载 // f()但是调用时会报错存在歧义编译器不知道调用谁 void f1() { cout f() endl; } void f1(int a 10) { cout f(int a) endl; } int main() { Add(10, 20); Add(10.1, 20.2); f(); f(10); f(10, a); f(a, 10); return 0; }八、引用8.1 引用的概念通俗的讲引用就是给一个已经存在的变量起别名并不会新开辟空间与引用的变量公用同一份内存空间。我们可以举一个例子林冲和豹子头豹子头就是林冲的别名但本身指的都是这个人。使用类型 引用别名 引用对象int a 10; int b a;8.2 引用的特性引用在定义的时候必须初始化一个变量可以有多个引用引用也可以嵌套引用引用一旦已经引用一个实体就不要再引用其他实体8.3 引用的使用引用传参通过引用传递参数可避免对象拷贝提升效率同时允许函数内部修改外部变量。与指针功能类似但语法更简洁void swap(int a, int b) { int tmp a; a b; b tmp; }对比指针传参引用无需解引用操作代码可读性更高。引用返回值函数返回引用时需注意返回对象的生命周期。典型应用包括返回类成员变量或静态变量int getMax(int a, int b) { return a b ? a : b; }引用与指针的区别不可变性C引用初始化后不能更改指向指针可重新赋值。安全性引用无空值nullptr风险指针需显式检查。语法引用直接操作对象指针需解引用。sizeof含义引用结果为引用类型大小指针结果始终是地址空间所占的字节数。int x 10; int ref x; // 正确 // int ref2; // 错误引用必须初始化 int* ptr x; // 指针可后期修改 ptr nullptr; // 合法java中引用可以改变指向8.4 const引用当引用一个const对象的时候必须使用const引用因为权限可以缩小不能放大。要注意在使用int ra a * 10 或者 double b 1.0;int rb b产生类型转换的时候结果都会先存入一个临时对象里面而C规定临时对象具有常性不可改变所以也需要使用const引用。即const 类型 引用别名 引用对象九、inline可以简单理解为宏函数但因为宏函数容易出错所以Inline的作用就是替代宏函数。用Inline修饰的函数叫做内联函数会在调用的时候建立栈帧自动展开提高效率inline对于编译器只是一个建议也就是说即使你加了inline编译器也可以选择不调用。inline适用于短小并且频繁调用的函数。而递归函数或者代码多的函数编译器一般会选择忽略。vs编译器的debug版本是默认不展开inline函数的如果想要设置需要修改两个地方inline函数不建议声明和定义分离到两个文件中分离会导致链接错误。因为Inline被展开后就没有了函数地址链接的时候会找不到十、nullptrnullptr是C的一个关键字用于表示空指针。解决了传统NULL宏的安全问题在C中NULL会被字面定义为0或者void*)0,当想要通过F(NULL调用Fint*)时会被调用为Fint x)与程序初衷相悖。所以引入了nullptr可以被转换为任意类型的指针类型。nullptr只能被隐式的转换为指针类型不能被转换为整数类型。#includeiostream using namespace std; void f(int x) { cout f(int x) endl; } void f(int* ptr) { cout f(int* ptr) endl; } int main() { f(0); // 本想通过f(NULL)调用指针版本的f(int*)函数但是由于NULL被定义成0调用了f(int x)因此与程序的初衷相悖。 f(NULL); f((int*)NULL); // 编译报错error C2665: “f”: 2 个重载中没有一个可以转换所有参数类型 // f((void*)NULL); f(nullptr); return 0; }小编说下一章节小编带大家看一看C的类和对象章节难度即将飙升哦有什么问题可以私信问我