✧(≖ ◡ ≖✿
目录
restrict修饰指针类型
1. 什么是“别名(Alias)”问题?
2. restrict 如何解决这个问题?
enum class强类型枚举C++11
原枚举体可能出现的问题(具体由环境决定)
1.命名空间污染
2.隐式转换为整数
enum class 的解决方案
std::function<返回类型(参数列表)>
std::function含义
private函数无法被当做参数
uint32_t 及 u_int32_t
string转换为char*、char*转换为string
关于void**
restrict修饰指针类型
是C99引入的关键字表示这个指针是访问其指向数据的唯一方式。
1. 什么是“别名(Alias)”问题?
看一个简单的例子,假设有两个指针a和b:
void 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如何解决这个问题?
c
void 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强类型枚举C++11
原枚举体可能出现的问题(具体由环境决定)
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 lgLvel=LogLevel::DEBUG; // ✅ 必须加作用域 }std::function<返回类型(参数列表)>
定义函数/函数对象
例如:
#include<functional> using func_t = std::function<void()>;std::function<void()>含义
void:返回类型为void。
():无参数。
含义:可以存储任何无参数、无返回值的函数/函数对象。
#include <functional> #include <iostream> // 普通函数 void hello() { std::cout << "Hello, World!" << std::endl; } int main() { std::function<void()> 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_t | uint32_t |
|---|---|---|
| 来源 | BSD 系统(Unix 传统) | C99/C++11 标准 |
| 头文件 | <sys/types.h> | <stdint.h>(C)<cstdint>(C++) |
| 标准化 | 非标准(BSD 扩展) | ✅ 标准(ISO C/C++) |
| 可移植性 | 主要 BSD/Linux 系统 | ✅ 所有支持 C99/C++11 的平台 |
| 命名风格 | u_前缀(BSD 风格) | _t后缀(标准风格) |
| 定义方式 | typedef unsigned int u_int32_t; | typedef unsigned int uint32_t; |
string转换为char*、char*转换为string
char* 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; }感谢支持,长期连载
欢迎关注