尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

C++20 高级编程 002:夯实现代C++底层基本功

C++20 高级编程 002:夯实现代C++底层基本功 C20 高级编程 002夯实现代C底层基本功前言Bilibili 同步视频一、告别头文件混乱C20 Module 模块系统核心规则完整可运行示例二、分支控制全解if/else、switch 双巨头C20 新增初始化语法1. if/else级联判断 内置初始化器2. switch 语句枚举匹配、穿透处理、同样支持初始化高频坑case 穿透 fallthrough三、简洁万能表达式三元条件运算符:四、逻辑与比较运算符短路求值 太空飞船 运算符1. 基础运算符清单 短路特性2. C20 王牌三向比较运算符 太空飞船运算符五、现代 C 函数体系自动返回值、重载、编译期内置变量1. 基础声明与定义2. auto 自动推导返回类型3. **func** 获取当前函数名4. 函数重载六、编译器属性 [[xxx]]给编译器传递提示规避警告、优化分支七、数组选型摒弃老旧 C 数组优先 std::array1. C 风格原生数组痛点2. std::array 标准固定数组容器推荐首选结语前言不少刚上手现代 C 的开发者还停留在 C 语言式的老旧写法里既错过 C20 带来的便捷新特性又容易踩各种隐性 bug。今天我们把 C20 最核心的入门语法串讲一遍涵盖模块化编程、各类分支控制、新式运算符、函数设计、编译属性、数组容器六大板块搭配可直接运行的示例代码轻松吃透现代 C 基础语法避开无数新手高频坑✨Bilibili 同步视频C20 高级编程 002夯实现代C底层基本功一、告别头文件混乱C20 Module 模块系统在 C20 之前项目依赖.h头文件反复包含宏污染、重复引入、编译缓慢都是家常便饭。而模块module彻底重构了代码导入导出逻辑核心靠export控制对外可见内容。核心规则export module xxx;定义独立模块export修饰结构体、函数外部导入后才能访问不加export仅模块内部可用导入标准库用尖括号import xxx导入自定义模块禁止尖括号直接写模块名。完整可运行示例// employee.ixx 模块接口文件exportmoduleemployee;// 导出结构体外部模块可直接使用exportstructEmployee{charfirstInitial;charlastInitial;intemployeeNumber;intsalary;};// main.cppimportiostream;importformat;importemployee;usingnamespacestd;intmain(){// 实例化员工结构体并赋值Employee staff{};staff.firstInitialL;staff.lastInitialW;staff.employeeNumber1001;staff.salary150000;// format格式化输出可读性远优于老式printfcoutformat(员工简称{}{}n,staff.firstInitial,staff.lastInitial);coutformat(工号{}n,staff.employeeNumber);coutformat(年薪${}n,staff.salary);return0;}对比传统头文件模块不会产生全局污染编译速度大幅提升大型工程维护体验直接拉满。二、分支控制全解if/else、switch 双巨头C20 新增初始化语法业务逻辑离不开条件判断C 提供两套分支体系同时新增初始化器语法大幅精简代码层级。1. if/else级联判断 内置初始化器普通 if-else if-else 逻辑无需多讲记住一条铁律表达式中0 等价 false非 0 全部视为 true。而 C17 起支持if(初始化语句; 判断条件)初始化的变量生命周期仅限整条 if 分支局部性更强减少无用变量污染全局作用域。示例场景读取员工信息同时判断薪资阈值// 复用上方Employee结构体intgetEmployee(){return9000;}intmain(){// if内置初始化临时获取薪资仅分支内可用if(intsalarygetEmployee();salary10000){coutformat(高薪员工薪资{}n,salary);}elseif(salary5000){coutformat(普通薪资薪资{}n,salary);}else{coutformat(基础薪资薪资{}n,salary);}// 此处无法访问salary变量生命周期已结束return0;}2. switch 语句枚举匹配、穿透处理、同样支持初始化switch 匹配类型受限仅整型、可转整型类型、枚举、强枚举只能和常量对比。高频坑case 穿透 fallthrough如果 case 末尾不写break代码会顺序执行下一个 case 逻辑绝大多数场景是 bug但如果是刻意穿透必须加[[fallthrough]]属性消除编译器警告。enumclassMode{Custom,Standard,Default};intmain(){Mode runModeMode::Custom;intvalue0;switch(runMode){usingenumMode;caseCustom:value84;// 刻意穿透标记属性避免告警[[fallthrough]];caseStandard:caseDefault:coutformat(当前配置数值{}n,value);break;default:cout未知运行模式n;break;}return0;}另外 switch 同样支持初始化语法switch(变量初始化; 匹配表达式)适合读取配置后直接分支判断。三、简洁万能表达式三元条件运算符:if 语句是语句不能嵌入赋值、打印等表达式场景而三元运算符是纯正表达式随时随地可用语法模板判断条件 ? 条件成立取值 : 条件不成立取值intnum10;// 直接嵌入cout输出代码极度精简cout(num5?数字大于5:数字小于等于5)endl;// 用于赋值场景std::string descnum%20?偶数:奇数;coutdescendl;小技巧问号可以理解为提问num5?翻译为 “num 大于 5 吗”记忆零难度。四、逻辑与比较运算符短路求值 太空飞船 运算符1. 基础运算符清单 短路特性运算符作用关键注意点判断相等切勿和赋值混淆新手高频 bug!不等于- 大小比较-!逻辑非取反一元运算符单操作数逻辑与左侧 false 直接短路右侧不执行逻辑或左侧 true 直接短路右侧不执行短路是一把双刃剑优势做指针判空、边界校验避免非法访问减少多余判断提升运行效率隐患若右侧包含函数调用、变量自增短路后代码不会执行隐藏难以复现的隐性 bug。2. C20 王牌三向比较运算符 太空飞船运算符传统写法判断两个数字大小至少需要两次比较一次运算就能区分小于、等于、大于三种关系返回标准化排序类型。整数std::strong_orderingless / equal / greater浮点数std::partial_ordering存在 unordered对应 NaN 无效数值配套compare头文件工具函数is_eq/is_lt/is_gt简化结果判断#includecompare#includeiostreamintmain(){inta11,b5;autoresab;if(std::is_lt(res))couta bn;elseif(std::is_eq(res))couta bn;elseif(std::is_gt(res))couta bn;return0;}大型自定义类对比场景优势巨大仅执行一次比较逻辑代替两次昂贵的成员比对性能收益显著。五、现代 C 函数体系自动返回值、重载、编译期内置变量函数是代码拆分的核心单元C 在 C 基础上拓展了大量实用特性。1. 基础声明与定义声明函数原型仅描述调用规则定义携带函数实体无返回值标注void无参数直接空括号无需写void和 C 区分。2. auto 自动推导返回类型不用手动写返回值编译器根据return表达式自动推导多 return 语句返回类型必须统一。// 自动推导返回值为intautoadd(inta,intb){returnab;}3.func获取当前函数名内置局部变量快速实现日志埋点调试神器autoadd(inta,intb){std::coutformat(进入函数{}n,__func__);returnab;}4. 函数重载同名函数依靠参数数量 / 参数类型区分仅返回值不同无法重载编译器会根据实参自动匹配版本// 整数重载intcalc(inta,intb){returnab;}// 浮点重载doublecalc(doublea,doubleb){returnab;}六、编译器属性 [[xxx]]给编译器传递提示规避警告、优化分支C11 标准化双方括号属性用来给编译器附加额外提示日常开发最常用 5 种[[nodiscard]]修饰带返回值函数调用时忽略返回值会触发编译警告C20 支持附加说明文字专门用来防止遗漏错误码[[nodiscard(返回错误码不可忽略)]]intcheckAuth(){return1;}intmain(){checkAuth();// 编译器抛出警告提醒丢弃返回值return0;}[[maybe_unused]]屏蔽 “变量 / 参数未使用” 警告接口预留占位参数必备voidtest(inta,[[maybe_unused]]intreserveParam){coutaendl;}[[noreturn]]标记函数永远不会返回调用方程序退出、抛出异常消除 “分支无返回值” 编译报错#includecstdlib[[noreturn]]voidexitApp(){std::exit(-1);}[[deprecated (“替换为 newFunc 接口”)]]标记接口废弃调用时告警用于版本迭代淘汰旧 API。[[likely]] / [[unlikely]]标记高 / 低概率分支辅助编译器做底层指令优化仅极致性能场景使用。七、数组选型摒弃老旧 C 数组优先 std::array1. C 风格原生数组痛点长度必须是常量不支持变量动态长度下标从 0 开始极易越界隐式转为普通指针丢失长度信息传递后无法获取大小初始化示例intarr[5]{};// 全部初始化为0intarr2[]{1,2,3};// 编译器自动推导长度为3获取长度两种方式#includearrayintarr[5]{};size_t len1std::size(arr);// 现代标准推荐size_t len2sizeof(arr)/sizeof(arr[0]);// 老式写法2. std::array 标准固定数组容器推荐首选定义于array对 C 数组轻量封装解决原生数组全部缺陷自带 size ()、不会隐式转指针、支持迭代器模板格式std::array元素类型, 固定长度#includearray#includeiostream#includeformatintmain(){std::arrayint,4nums{10,20,30,40};coutformat(容器长度{}n,nums.size());coutformat(第二个元素{}n,nums[1]);return0;}结语以上覆盖了 C20 入门阶段最核心的语法体系从模块化工程管理、分支逻辑、新式运算符到函数规范、编译属性、容器数组每一块都配套可直接编译运行的代码。现代 C 早已摆脱 C 语言粗糙的语法束缚合理运用模块、初始化分支、运算符、std::array 等新特性既能减少 80% 新手 bug又能提升代码可读性与运行性能。后续我们可以基于这些基础继续深挖类、模板、标准容器等进阶内容逐步构建完整的现代 C 知识栈。
返回列表