【C语言笔记】【有点逗系列】 使用goto语句实现switch语句的功能

【C语言笔记】【有点逗系列】 使用goto语句实现switch语句的功能,第1张

【C语言笔记】【有点逗系列】 使用goto语句实现switch语句的功能 【C语言笔记】【有点逗系列】 使用goto语句实现switch语句的功能

有点逗系列内容。用于记录各式各样有点逗甚至没有什么用的C语言用法☺。

功能说明

功能就是使用goto语句实现switch语句的功能。

该功能基于GNU对C语言扩展功能:标签作为值(Labels as Values)。

也就是对Labels as Values这个扩展功能的一种使用方式,实现的这个switch功能实际并没啥用。

实现代码
void goto_switch(unsigned int val) {
    static void* array[] = { &&lable0, &&lable1, &&lable2, &&lable3, &&lable4, &&lable5};
    
    if(val >= (sizeof(array)/sizeof(void*)))
        goto other;
    
    goto *array[val];
lable0:
    printf("lable0n");
    goto end;
lable1:
    printf("lable1n");
    goto end;
lable2:
    printf("lable2n");
    goto end;
lable3:
    printf("lable3n");
    goto end;
lable4:
    printf("lable4n");
    goto end;
lable5:
    printf("lable5n");
    goto end;
other:
    printf("other %dn", val);
end:
    return;
}

这个程序就是使用goto语句实现switch语句的功能,实现的效果就是val的值为0,1,2,3,4,5的时候打印lable0,lable1,lable2,lable3,lable4,lable5,其他值的话直接打印出来。

效果与下面的这个使用switch语句的程序相同。

void real_switch(unsigned int val) {
    
    switch(val)
    {
        case 0:
        printf("lable0n");
        break;
        
        case 1:
        printf("lable1n");
        break;
        
        case 2:
        printf("lable2n");
        break;
        
        case 3:
        printf("lable3n");
        break;
        
        case 4:
        printf("lable4n");
        break;
        
        case 5:
        printf("lable5n");
        break;
        
        default:
        printf("other %dn", val);
    }
    return;
}
示例程序
int main(int argc, char* argv[])
{
    for(int i = 0; i < 10; i++)
        goto_switch(i);
    
    return 0;
}

运行结果就是:

lable0
lable1
lable2
lable3
lable4
lable5
other 6
other 7
other 8
other 9
实现原理

实现的原理就是基于GNU对C语言扩展功能Labels as Values。

GNU的Labels as Values功能就是,可以使用运算符“&&”获取当前函数中定义的标签(label)的地址,值的类型为void *。如下:

void *ptr;
ptr = &&foo;

要使用这个值的方式如下:

goto *ptr;

该功能允许使用void*类型的任何表达式。

基于上述的功能,接下来就可以使用goto语句实现switch语句的功能了。

先要定义要有多少分支,如下:

static void* array[] = { &&lable0, &&lable1, &&lable2, &&lable3, &&lable4, &&lable5};

跳转方式如下:

    goto *array[val];

这个类似于switch:

    switch(val)

将预先定义好的分支对应的标签实现好:

lable0:
    printf("lable0n");
    goto end;

这个类似于case:

        case 0:
        printf("lable0n");
        break;

其中的goto end相当于break。

还需要应对其他情况:

if(val >= (sizeof(array)/sizeof(void*)))
        goto other;
other:
    printf("other %dn", val);

这个类似于default:

        default:
        printf("other %dn", val);

这样就实现了使用goto语句实现switch语句的功能。

[参考资料]

【GNU笔记】【C扩展系列】标签作为值

6.3 Labels as Values


本文链接:https://blog.csdn.net/u012028275/article/details/122444065

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5710601.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存