有没有办法用这个switch语句减少代码行数?我可以使用for循环但不重新分配ci值吗?或者这是基于逻辑表达式的分配方面最优化的吗?
char ci, co;
while (fscanf(fp1, "%c", &ci) != EOF) {
switch(ci) {
case 97:
co = 33;
break;
case 98:
co = 34;
break;
case 99:
co = 35;
break;
case 100:
co = 36;
break;
case 101:
co = 37;
break;
case 102:
co = 38;
break;
case 103:
co = 39;
break;
case 104:
co = 40;
break;
case 105:
co = 41;
break;
case 106:
co = 42;
break;
case 107:
co = 43;
break;
case 108:
co = 44;
break;
case 109:
co = 45;
break;
case 110:
co = 46;
break;
case 111:
co = 47;
break;
case 112:
co = 48;
break;
case 113:
co = 49;
break;
case 114:
co = 50;
break;
case 115:
co = 51;
break;
case 116:
co = 52;
break;
case 117:
co = 53;
break;
case 118:
co = 54;
break;
case 119:
co = 55;
break;
case 120:
co = 56;
break;
case 121:
co = 57;
break;
case 122:
co = 58;
break;
case 48:
co = 59;
break;
case 49:
co = 60;
break;
case 50:
co = 61;
break;
case 51:
co = 62;
break;
case 52:
co = 63;
break;
case 53:
co = 64;
break;
case 54:
co = 65;
break;
case 55:
co = 66;
break;
case 56:
co = 67;
break;
case 57:
co = 68;
break;
case 32:
co = 69;
break;
case 10:
co = 70;
break;
case 13:
co = 71;
break;
default:
break;
}
fprintf(fp2, "%c", co);
}
答案 0 :(得分:3)
正如其他人已经观察到的那样,您可以利用开关值和输出值之间的函数关系。然而,更好的是使用查找表:
#include <limits.h>
#include <stdio.h>
void f() {
static const unsigned char table[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 70, 11, 12, 71, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
69, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 123, 124, 125, 126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 123, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
};
char ci, co;
while (fscanf(fp1, "%c", &ci) != EOF) {
#if CHAR_MIN < 0
/* default char is signed -- watch out for negative values! */
unsigned char uc = table[(unsigned char) ci];
co = (uc <= CHAR_MAX) ? uc : (uc - (UCHAR_MAX + 1));
#else
/* default char is unsigned -- all clear */
co = table[ci];
#endif
fprintf(fp2, "%c", co);
}
}
总的来说,它并不像某些替代方案那么短,但它的速度非常快,特别是在具有无符号默认char
的系统上。当然,如果你只计算循环体,那么你几乎不会变短。
顺便说一下,请注意,原始代码会为从文件扫描的许多可能值产生未定义的行为,因为它只为co
的某些值设置ci
,但它读取在每种情况下的价值。在你至少设置一次之前,你不应该读它的价值。即使在你设置了一次它的值之后,你实际上想要在下一个循环迭代中可能携带该值似乎令人惊讶。另一方面,查找表版本始终设置co
,通常设置为与ci
相同的值。
请注意,这取决于UCHAR_MAX
为255
(或更少);如果它更大,则表查找可以访问超过表的末尾。如果你真的担心你的代码在unsigned char
超过8位的机器上运行,你可以通过编程初始化查找表来解决这个问题。
答案 1 :(得分:1)
使用if / else对您拥有的几种模式进行分组。所以:
char ci, co;
while (fscanf(fp1, "%c", &ci) != EOF) {
if ( ci => 97 && ci <= 122 ) {
co = ci - 64;
} else if ( ci => 48 && ci <= 57) {
co = ci + 11;
} else if ( ci == 32 ) {
co = 69;
} else if ( ci == 10 ) {
co = 70;
} else if ( ci == 13 ) {
co = 71;
} else {
printf("Unhandled case: ci = %d\n", ci);
}
fprintf(fp2, "%c", co);
}
编辑:添加其余案例。
答案 2 :(得分:1)
也许使用一些ifs:
if(ci>96){
co=ci-64;
}elseif(ci>47){
co=ci+11;
}elseif(ci==32){
co=69;
}elseif(ci==10){
co=70;
}elseif(ci==13){
co=71;
}
比其他代码更干净。试着通过计算来破坏相同的案例。
答案 3 :(得分:1)
通过将检查分解为我在案例中看到的图案范围,这更加简洁。
if (ci >= 97 && ci <= 122){
co = 33 + (ci - 97);
}
else if (ci >= 48 && ci <= 57){
co = 59 + (ci - 48);
}
else if (ci == 32){
co = 69;
}
else if (ci == 10){
co = 70;
}
else if (ci == 13){
co = 71;
}
答案 4 :(得分:0)
减少开关
switch(ci) {
case 97:
case 98:
case 99:
case 100:
case 101:
case 102:
case 103:
case 104:
case 105:
case 106:
case 107:
case 108:
case 109:
case 110:
case 111:
case 112:
case 113:
case 114:
case 115:
case 116:
case 117:
case 118:
case 119:
case 120:
case 121:
case 122:
co = 33 + (ci - 97);
break;
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57:
co = 59 + (ci - 48);
break;
case 32:
co = 69;
break;
case 10:
co = 70;
break;
case 13:
co = 71;
break;
default:
break;
}