C语言语法笔记
C语言语法笔记常见的switch caseswitch(opcode){ case 0b00000000: //每一个都要带break; add(inst); //别忘了default break; //每个情况前面都有case case 0b10000000: //默认十进制,二进制十六进制要加0b0x li(inst); break; case 0b11000000: bner(inst); break; default: log_err(不存在指令); break; }位操作int a; a 2; //a 0b100 - 0b11100uint32_t b; b 2; //b 0b100 - 0b00100二者区别是int带有符号位,右移会自动符号拓展,高位与符号位相同imm 20 20; //利用上述特性,先将int型立即数移到最高位,再右移,实现自动符号扩展uint32_t a1; uint32_t a2; uint32_t a3; uint32_t a4; uint32_t a; a ((a1 0xff) 24) | ((a2 0xff) 16) | ((a3 0xff) 8) | (a4 0xff); //通过移位操作和按位或按位与可实现位拼接 //!!!注意要加括号,的优先级最高-公式都加括号算术运算ab b (ab - g)(i / k); //C会把(ab - g)认为是函数 两个数相乘要加* ❌ ab b (ab - g) * (i / k); //不要忘了* ✅没见过的东西## #在C语言中##可以把左右拼接成一个新的标记#可以把变量内容转换成字符串A AM##1; //A AM1 string str #(1 2 3) //str 1 2 3在标准的 C 语言中{ … } 只是单纯的代码块没有返回值。但 GCC 扩展允许写 ({ 语句1; 语句2; 变量; })这个结构的返回值就是最后一行的那个变量。像是一个小函数?#define io_read(reg) \ ({ reg##_T __io_param; \ // 第1行 语句1 ioe_read(reg, __io_param); \ // 第2行 语句二 __io_param; }) // 第3行 返回值((handler_t)lut[reg])(buf); //可以拆成三部分lut[reg]从数组 lut 中取出第 reg 个元素。这个元素是一个函数指针指向某个函数的地址。(handler_t)这是一个强制类型转换。它把 lut[reg] 这个值强制转换成 handler_t 类型。(buf)是前面函数的参数void (*handler_t)(void *buf);指向一个接收handler_t参数、返回 void 的函数的指针。#define AM_DEVREG(id, reg, perm, ...) \ enum { AM_##reg (id) }; \ typedef struct { __VA_ARGS__; } AM_##reg##_T; //用这个宏定义了很多结构体 AM_DEVREG( 1, UART_CONFIG, RD, bool present);调用这个宏会生成对应的结构体,结构体名由拼接得来例如AM_DEVREG( 1, UART_CONFIG, RD, bool present);等价于typedef struct { bool present; }AM_UART_CONFIG_T;结果是AM_UART_CONFIG 1结构体有一个成员present