C语言语法笔记

📅 2026/7/10 1:20:35 👁️ 阅读次数 📝 编程学习
C语言语法笔记

C语言语法笔记

常见的

switch case

switch(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 -> 0b11100
uint32_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