bit::Shadow✧(≖ ◡ ≖✿目录restrict修饰指针类型1. 什么是“别名Alias”问题2. restrict 如何解决这个问题enum class强类型枚举C11原枚举体可能出现的问题具体由环境决定1.命名空间污染2.隐式转换为整数enum class 的解决方案std::function返回类型(参数列表)std::function含义private函数无法被当做参数uint32_t 及 u_int32_tstring转换为char*、char*转换为string关于void**restrict修饰指针类型是C99引入的关键字表示这个指针是访问其指向数据的唯一方式。1. 什么是“别名Alias”问题看一个简单的例子假设有两个指针a和bvoid func(int *a, int *b) { *a 10; *b 20; *a *a 5; // 这里的 *a 需要重新从内存读取吗 }编译器不知道a和b是否指向同一块内存。如果a b即指向同一个地址那么*b 20会改变*a的值。所以编译器必须保守地认为a和b可能重叠每次使用*a时都要重新从内存读取而不能直接用寄存器里缓存的旧值。这种“保守”策略会阻止编译器进行优化。2.restrict如何解决这个问题cvoid func(int *restrict a, int *restrict b) { *a 10; *b 20; *a *a 5; // 编译器知道 a 和 b 不重叠所以可以直接用寄存器里的 10 }程序员通过restrict向编译器做出承诺a和b不会指向同一块内存。编译器收到这个承诺后可以放心地优化在执行*b 20后它知道*a没有被修改所以可以直接用寄存器里的值10来计算*a 5无需重新从内存读取。enum class强类型枚举C11原枚举体可能出现的问题具体由环境决定1.命名空间污染enum LogLevel { DEBUG, INFO, WARN, ERROR, FATAL };枚举体内定义的名字会转为“全局变量”。2.隐式转换为整数// ❌ 传统 enum enum LogLevel { DEBUG, INFO, WARNING, ERROR, FATAL }; enum Fruit { APPLE, // 冲突APPLE 已经存在!!! BANANA, ORANGE }; void func(LogLevel level) {} int main() { func(10); // ❌ 可以传入任意整数 int x WARNING; // ❌ 隐式转换为 int x x 5; // ❌ 可以参与算术运算 if (INFO 1) { // ❌ 可以与整数比较 // ... } return 0; }enum class 的解决方案enum class LogLevel { DEBUG, INFO, WARNING, ERROR, FATAL }; void test(){ LogLevel lgLvelLogLevel::DEBUG; // ✅ 必须加作用域 }std::function返回类型(参数列表)定义函数/函数对象例如#includefunctional using func_t std::functionvoid();std::functionvoid()含义void:返回类型为void。():无参数。含义可以存储任何无参数、无返回值的函数/函数对象。#include functional #include iostream // 普通函数 void hello() { std::cout Hello, World! std::endl; } int main() { std::functionvoid() func hello; // 存储普通函数 func(); // 调用Hello, World! return 0; }private函数无法被当做参数uint32_t 及 u_int32_t是一种类型别名保证在任何平台下均为“32位无符号整数”4字节。保证了兼容性。再有int8_t、uint64_t等扩展性C/C类型均是为了兼容平台。正规C/C标准注意无ulong64_t。除此之外还有u_int32_t等相似形式这是BSD系统标准兼容性较差。对比如下方面u_int32_tuint32_t来源BSD 系统Unix 传统C99/C11 标准头文件sys/types.hstdint.hCcstdintC标准化非标准BSD 扩展✅ 标准ISO C/C可移植性主要 BSD/Linux 系统✅ 所有支持 C99/C11 的平台命名风格u_前缀BSD 风格_t后缀标准风格定义方式typedef unsigned int u_int32_t;typedef unsigned int uint32_t;string转换为char*、char*转换为stringchar* name _name.c_str();char*转换为string可以隐式转换少用库函数实现。关于void**int main() { // printf(%d\n,ThreadModule::number); //void**对地址的作用 // void a 10;//wrong!! int a 10; int* pa a; printf(%p\n, pa); printf(%p\n, (void*)pa); // cout *(void*)pa);wrong 无法打印空类型 // printf(%p\n, **(void**)pa); printf(%p\n, (void**)pa);//double转换为int可能值改变。此处不变是因为解析方式不变。 printf(%p\n, *(void**)pa); return 0; }感谢支持长期连载欢迎关注