在 C 中执行案例 a ... z 的便携式方法

Portable way to do case a ... z in C

我正在使用以下 GCC 扩展来简化一个大的 switch 语句:

case 'a' ... 'z':
   ...

执行此操作的 proper/portable 方法是什么 -- 即,遍历一个大开关中的所有字母 -- 或者为此不应该使用开关。

如果您希望所有大小写 'a' 到 'z'(所有小写字母)都具有相同的效果,那么您可以执行以下操作

#include <ctype.h>

if(isalpha(c) && islower(c))
{
        //..Do Whatever... 
}

请记住,当 none 的情况为真时,default 可用于执行任务:

switch (x)
{
    case 1:
    case 2:
        printf("%d\n", x);
        break;
    default:
        if (islower(x))
        {
            puts("alpha");
        }
        break;
}

另一种使用臭名昭著的方法 goto:

if (islower(x))
    goto alpha;

switch (x)
{
    alpha:
        printf("alpha\n");
        break;
    case 1:
    case 2:
        printf("%d\n", x);
        break;
}

我会'go through all the letters in a big switch'.
仅仅是因为编译器(gcc 或 clang)将再次优化此 'away'。 如果您比较以下代码:

void func0(int x)
{
    switch( x )
    {
    case 'a':case 'b':case 'c':case 'd':case 'e':
    case 'f':case 'g':case 'h':case 'i':case 'j':
    case 'k':case 'l':case 'm':case 'n':case 'o':
    case 'p':case 'q':case 'r':case 's':case 't':
    case 'u':case 'v':case 'w':case 'x':case 'y':
    case 'z':
        func1(x);
        break;
    case 1001:
        func2(x);
        break;
    default:
        func3(x);
        break;
    }
}

生成汇编代码 (gcc) (注意:97== 'a' 和 122 == 'z'),它基本上将您的代码更改为 类似于 if(c>'z')if(c<'a') 的东西:

func0:
        push    rbp
        .seh_pushreg    rbp
        mov     rbp, rsp
        .seh_setframe   rbp, 0
        sub     rsp, 32
        .seh_stackalloc 32
        .seh_endprologue
        mov     DWORD PTR 16[rbp], ecx
        cmp     DWORD PTR 16[rbp], 122
        jg      .L2
        cmp     DWORD PTR 16[rbp], 97
        jge     .L3
        jmp     .L4
.L2:
        cmp     DWORD PTR 16[rbp], 1001
        je      .L5
        jmp     .L4
.L3:
        mov     ecx, DWORD PTR 16[rbp]
        call    func1
        jmp     .L6
.L5:
        mov     ecx, DWORD PTR 16[rbp]
        call    func2
        jmp     .L6
.L4:
        mov     ecx, DWORD PTR 16[rbp]
        call    func3
        nop
.L6:
        nop
        add     rsp, 32
        pop     rbp
        ret

因此生成的汇编代码针对速度和大小进行了优化。