你如何在C中定义一个常量?

时间:2012-03-31 13:31:19

标签: c const

我正在尝试构建一个开关,我得到一个“表达式必须具有整数或枚举类型”。我猜测winapi中的切换不采用LPSTR类型的变量?

char testbuf[ 51 ]; // allocate space for 50 characters + termination
LPSTR test = testbuf;
scanf("%50s", test); // read at most 50 characters
printf("%s", test);
switch ( test ) {
    case "etc" :
        {

        }
    break;

4 个答案:

答案 0 :(得分:4)

这与WinAPI无关,它只是简单的C.你可以switch唯一可以是整数(intchar和类似的)或枚举类型,比如你的编译器正在告诉你。

如果您需要“切换”字符串,则需要自行构建if / else序列并使用strcmp或其变体。

答案 1 :(得分:1)

我通常使用一种字典模式:

enum {
    keyETC,
    keyOther,
    keyUnknown
};
struct SDictionary{
    int key;
    char *name;
} dict[] = {
    { keyETC, "etc" },
    { keyOther, "bla" },
    { 0 }
};

// lookup
struct SDictionary *pCandidate = dict;
int key = keyUnknown;

while (pCandidate->name)
{
    if (0 == strcmp(test, pCandidate->name)
    {
         key = pCandidate->key;
         break;
    }
}

switch (key)
{
    case keyETC:
    // ....
}

答案 2 :(得分:0)

在常规情况下,您需要将字符串与字符串比较算法进行比较,如下所示:

if(strcmp(test, "etc") == 0) {
  ...
}

然而,有趣的是,如果字符串可以通过前4个字节唯一标识,并且您需要更优化的开关,则可以执行以下操作:

#include <Windows.h>
#include <stdio.h>

int main(void)
{
  LPSTR test = "etc";

  switch(*(DWORD *)test) {
  case 'cte':
    puts("etc case");
    break;
  default:
    puts("not hit");
    break;
  }

  return ERROR_SUCCESS;
}

这会将etc case打印到控制台,因为我们接受字符串指针并将其视为DWORD指针。然后将指针解除引用,并与字符串的DWORD值进行比较。在这种情况下,字符串只有3个字符长,但如果我们在末尾考虑空终止符,它可以由前4个字节唯一标识。

注意:应该注意,此技巧仅适用于允许对内存进行未对齐访问的体系结构。原因是字符串可能不是DWORD对齐的。

答案 3 :(得分:0)

C在char数组上没有大小写。仅支持整数值。

如果您知道要用作switch参数的字符串的长度不超过整数类型的大小,则可以将char数组的字符重新解释为数字。

char *test = "etc";
int NumericalValue = 0;
int size = min(sizeof(NumericalValue), strlen(test) + 1);
memcpy(&NumericalValue, test, size)

如果有这个数字,可以在switch语句中使用数字常量:

// you need to adapt the actual values to your architecture's representation of numbers.
const int keyETC = 0x00635445;

switch (NumericalValue)
{
case keyETC:
    puts("etc case");
    break;
default:
    ....
}