C语言杂记知识点
运算里的坑uint32_t Read; // 本次读取的 编码器原始计数值 uint32_t Record; // 上一次读取的 编码器计数值用于计算差值 int C_Value; // 本次周期的 增量值处理溢出后正/负表示方向 C_Value (int32_t)(Read - Record;因为Read和Record都是uint32_t 无符号整型如果直接写C_Value (int32_t)(Read - Record);运算顺序是先执行Read - Record按照无符号数规则计算当Read Record时比如 50 - 100无符号减法会下溢得到一个巨大的正数如 4294967246最后才强制转换为int32_t此时错误已经发生强转无法挽回所以这种写法本质上是错的强转放括号外没有任何修正作用。正确写法 正确逻辑C_Value (int32_t)Read - (int32_t)Record;正确逻辑是先把两个无符号变量强制转换成有符号 int32_t再进行减法运算运算全程按照有符号数规则执行无论正转反转都能得到正确的正 / 负无符号数相减先算再强转 溢出已经发生无法修复先强转有符号再相减 运算规则正确结果永远安全。注释知识点/* 注释(可跨行) */ //注释 #if 0 代码块 #endif/* 注释 */ 这个可以注释代码块但是不能嵌套用// 双斜杠注释双斜杠后边的文字、代码等等#if 0 ... #endif 内可以嵌套任何注释、任何代码前向声明typedef uint32_t (*encoder_read_func_t)(uint8_t encoder_id); typedef void (*encoder_send_func_t)(const Encoder_Data *encoder); typedef struct _Encoder_Data { uint32_t Read; uint32_t Record; int32_t C_Value; int32_t Send_value; uint32_t ticks; uint8_t encoder_id; encoder_read_func_t read_func; encoder_send_func_t send_func; EncoderState encoder_state; }Encoder_Data;我在编译时出现了一个典型的C 语言类型前置依赖问题报错信息为error: #20: identifier Encoder_Data is undefined报错位置在下面这行typedef void (*encoder_send_func_t)(const Encoder_Data *encoder);根本原因C 语言编译器是从上到下顺序解析的使用的类型必须先定义后使用。而我的代码出现了双向依赖环形依赖发送函数指针encoder_send_func_t依赖Encoder_Data结构体类型Encoder_Data结构体内部又需要存放encoder_send_func_t函数指针。直接后果如果把结构体放在前面结构体内部用到send_func但此时函数指针类型还未定义会报 “类型未定义”。如果把函数指针放在前面函数指针参数用到Encoder_Data*但此时结构体还未定义同样报 “标识符未定义”。这是一个典型的交叉引用编译问题单纯调整上下顺序无法解决必须使用结构体前向声明才能打破依赖环。其实就相当于函数声明前向声明声明有这个结构体后续定义结构体具体成员// 前向声明固定格式 typedef struct _结构体名字 结构体别名; // 等价两步合并前向声明 起别名 typedef struct _Encoder_Data Encoder_Data; typedef struct _Encoder_Data Encoder_Data; typedef void (*encoder_send_func_t)(const Encoder_Data *encoder); typedef struct _Encoder_Data { uint32_t Read; uint32_t Record; int32_t C_Value; int32_t Send_value; uint32_t ticks; uint8_t encoder_id; encoder_read_func_t read_func; encoder_send_func_t send_func; EncoderState encoder_state; }Encoder_Data;