有什么方法可以将具有常量索引的常量数组用作C中的开关案例标签? [英] Is there any way to use a constant array with constant index as switch case label in C?

查看:99
本文介绍了有什么方法可以将具有常量索引的常量数组用作C中的开关案例标签?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些常量值和数组,它们定义了标签和哈希码.例如,

I have some constant values and arrays defining their labels and their hash codes. For example,

#define LABEL_A 0 //or const int LABEL_A = 0;
#define LABEL_B 1
#define LABEL_C 2
#define LABEL_D 3

const char *VALUE[] = {"LABEL_A", "LABEL_B", "LABEL_C", "LABEL_D"};
const int VALUE_HASH[] = {67490, 67491, 67493, 67459);

在运行时,这些标签可以按任何顺序排列,并且需要相应地进行解析.我为此使用了开关盒. 此代码在编译时生成错误,需要使用常量表达式.

At run-time, these labels can come in any order and needs to be parsed accordingly. I am using switch case for this purpose. This code is generating error at compile time "constant expression is required.

function(const char* LabelAtRuntime){
  int i = getHashCode(LabelAtRuntime);
  switch(i){
    case VALUE_HASH[LABEL_A]: //line giving compile time error
      break;
    default:
      break;
}

但是,当我提供实际常量时,它就可以工作. 此代码效果很好.

But, when I provide actual constants, it works. This code works well.

function(const char* LabelAtRuntime){
  int i = getHashCode(LabelAtRuntime);
  switch(i){
    case 67490: //line not giving compile time error
      break;
    default:
      break;
}

  1. 我无法理解,为什么会发生?我的数组及其索引都是常量,那么它不等于常量文字吗?
  2. 还有其他方法可以按要求的方式提供常量吗?

我以这种方式使用常量来提供更好的代码语义,可读性和可重用性.请不要提供基于if-else的解决方案.在上面的示例中,标签只有4个,但实际上可能有100个标签.

I am using constants in this manner to provide better code semantics, readability and reusability. Please do not provide if-else based solution. In above example, there are only 4 labels, but in practical, there could be 100.

推荐答案

在C ++中,它将编译:

In C++, this compiles:

#include <stdio.h>
#include <stdlib.h>

constexpr int x[] = { 42, 43 };

int main(int argc, char **argv)
{
    switch(atoi(argv[1]))
    {
        case x[0]: puts("forty_two");
                   break;
        case x[1]: puts("forty_three");
    }
    return 0;
}

因此,数组上的constexpr似乎是现代C ++中的解决方案. (注意:该问题最初被标记为C ++和C)

So constexpr on the array appears to be the solution in modern C++. (Note: the question was originally tagged C++ and C)

如果要保留数组,在C语言中是不可能的.切换用例需要一个整数常量,但是一旦输入变量中的整数常量,它将成为运行时实体(即使已声明为const). 您可以做的就是用一堆直接定义替换内存数组,并可能有一个宏,它可以使用其他宏来查找宏(如果要保留代码形式):

It's impossible in C if you want to keep the array. Switch cases require an integer constant, but once you put an integer constant in a variable, it becomes a runtime entity (even if it's declared const). What you could do is replace the in-memory array with just a bunch of direct defines and possibly have a macro that looks up macros using other macros (if you want to keep your form of the code):

#define LABEL_A 0
#define LABEL_B 1
#define LABEL_C 2
#define LABEL_D 2

#define VALUE_HASH__0 67490
#define VALUE_HASH__2 67491
#define VALUE_HASH__3 67491
#define VALUE_HASH__4 64759

//append what Index expands to to VALUE_HASH__
#define HASH_LOOKUP(Index) MC_cat(VALUE_HASH__,Index) 
#define MC_cat_(X,Y) X##Y
#define MC_cat(X,Y) MC_cat_(X,Y)

function(const char* LabelAtRuntime){
  int i = getHashCode(LabelAtRuntime);
  switch(i){
    case HASH_LOOKUP(LABEL_A)
      break;
    default:
      break;
}

这篇关于有什么方法可以将具有常量索引的常量数组用作C中的开关案例标签?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆