有一种使用switch case 的情况,就是更具不同的枚举常量,去case设置一个对象不同的属性值。
比如:
struct A {
int p1;
int p2;
int p3;
} a;
enum {
one,
two,
three,
}
switch(n) {
case one:
a.p1 = 10;
break;
case two:
a.p2 = 10;
break;
case three:
a.p3 = 10;
break;
}
类似这种方式的使用,可以是更复杂的对象,更多的枚举,我们可以把这个switch case 给优化掉。
如下:
enum {
one = offsetof(A, p1),
two = offsetof(A, p2),
three = offsetof(A, p3),
}
// switch case 优化为一条语句
*(int*) ((char*) a + n) = 10;
1) 我们把枚举优化为对象属性的偏移量
2) 我们强转对象为char* 然后更具枚举计算偏移,得到属性所在的地址,然后赋值。
这样我们就可以在这种模式下优化掉switch case了。
小技巧一发:
主要还是,看待 switch case 的视角问题。
我们总是在 case 下面写代码,思考代码的结构,case穿透或不穿透。
特别的是,switch 之后的 { } 代表了作用域,除了可以处理 case 以外也具有作用域一般性的功能。
比如,书写定义任何语句。
举个例子:
switch (n) {
int a = 100;
a++;
case 1:
// 这里a是没有初始化的, 因为匹配caes会跳过语句赋值
// 但是已经定义了
a = 200;
break;
case 2:
a = 300;
break;
}
在 达夫设备 Duff’s Device 技巧中,甚至可以在把 case 放到 do while 之中。
这就给我们提供了新的思路和视角,去看待 switch case 的使用。