Mic*_*ael 28 c pointers switch-statement
例如:
#include <stdio.h>
void why_cant_we_switch_him(void *ptr)
{
switch (ptr) {
case NULL:
printf("NULL!\n");
break;
default:
printf("%p!\n", ptr);
break;
}
}
int main(void)
{
void *foo = "toast";
why_cant_we_switch_him(foo);
return 0;
}
gcc test.c -o test
test.c: In function 'why_cant_we_switch_him':
test.c:5: error: switch quantity not an integer
test.c:6: error: pointers are not permitted as case values
Run Code Online (Sandbox Code Playgroud)
只是好奇.这是技术限制吗?
人们似乎认为只有一个常量指针表达式.这是真的吗?举例来说,这里是在Objective-C(一种常见的范例是真的是仅含有C除了NSString,id并且nil,这仅仅是一个指针,所以它仍然是相关的-我只是想指出,有是,事实上,一个共同的使用它,尽管这只是一个技术问题):
#include <stdio.h>
#include <Foundation/Foundation.h>
static NSString * const kMyConstantObject = @"Foo";
void why_cant_we_switch_him(id ptr)
{
switch (ptr) {
case kMyConstantObject: // (Note that we are comparing pointers, not string values.)
printf("We found him!\n");
break;
case nil:
printf("He appears to be nil (or NULL, whichever you prefer).\n");
break;
default:
printf("%p!\n", ptr);
break;
}
}
int main(void)
{
NSString *foo = @"toast";
why_cant_we_switch_him(foo);
foo = kMyConstantObject;
why_cant_we_switch_him(foo);
return 0;
}
gcc test.c -o test -framework Foundation
test.c: In function 'why_cant_we_switch_him':
test.c:5: error: switch quantity not an integer
test.c:6: error: pointers are not permitted as case values
Run Code Online (Sandbox Code Playgroud)
看来原因是switch只允许整数值(如编译器警告所说).所以我想更好的问题是问为什么会这样?(虽然现在可能已经太晚了.)
Dig*_*oss 13
鉴于只存在一个常量指针表达式,该switch语句几乎没有提供指针表达式.你基本上引用了唯一可能的结构.
switch语句仅对整数表达式起作用.指针不是整数表达式.
如果您愿意,可以显式地将指针转换为整数类型,但建议的代码有点奇怪且不自然.
所以要准确回答你的问题:因为指针和整数类型之间没有隐式转换.
开关将变量与一组编译时常量进行比较.除了null之外,我看不到任何可以比较指针的有效编译时常量.例如:
switch (ptr) {
case &var1: printf ("Pointing to var1"); break;
case &var2: printf ("Pointing to var2"); break;
}
Run Code Online (Sandbox Code Playgroud)
var1和var2在程序的每次运行中可能都不同,并且不是编译时常量.一种可能性是它们是始终固定的内存映射端口的地址,但是我不知道如何从两种情况(null/not-null)中轻松扩展它.
将ptr转换为int并再试一次:
switch( (int)ptr )
Run Code Online (Sandbox Code Playgroud)
或者更正确:
switch( (intptr_t)ptr ) // C99 integer type to hold a pointer
Run Code Online (Sandbox Code Playgroud)
你可以(如果你真的必须的话)。只需将指针转换为适当大小的整数即可。为此intptr_t应使用。这并不是说我会推荐它,但你可能有你的理由。
#include <stdint.h>
#include <stdio.h>
void we_can_switch_him(void *ptr)
{
switch ((intptr_t)ptr) {
case (intptr_t)NULL:
printf("NULL!\n");
break;
default:
printf("%p!\n", ptr);
break;
}
}
int main(void)
{
void *foo = "toast";
we_can_switch_him(foo);
return 0;
}
Run Code Online (Sandbox Code Playgroud)