有没有办法简化这个陈述?

时间:2015-06-11 00:08:36

标签: c reduce simplify processing-efficiency

有没有办法用这个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);
}

5 个答案:

答案 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_MAX255(或更少);如果它更大,则表查找可以访问超过表的末尾。如果你真的担心你的代码在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;
}