- 已关闭**。此问题需要details or clarity。当前不接受答案。
- 想要改进此问题?**添加详细信息并通过editing this post阐明问题。
3小时前关门了。
截至3小时前,社区正在审查是否重新讨论此问题。
Improve this question
我有一个很长的if () ... else if () ... else if() ...
代码,类似于:
int token;
if((token >= 'a' && token <= 'z') || (token >= 'A' && token <= 'Z'))
// ...
else if (token == '\n')
// ...
else if (token == '^')
// ...
else if (token == '&')
// ...
它有很多'=='
和token >= 'a' && token <= 'Z'
的作用域,所以我想用switch
重写这个if else
,但是用case
匹配所有字母表很麻烦,我知道它可以写成下面的代码:
int token;
switch (token) {
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':
// ...
break;
}
但我认为这并不简洁,所以我想问是否有更简洁的方法来使用一个case
来匹配a-z
和A-Z
5条答案
按热度按时间p8h8hvxi1#
使用表格简化
switch()
。@user3386109这在某种程度上复制了
is...()
例程,但没有 * locale * variance * 1和2)可以根据您的解析需要进行定制。最好使用命名常量/
enum
,而不是1,2,3,4 ...我怀疑OP正在使用这段代码进行标记化,并且属于3%的时候,微优化是值得的。
is...()
函数都有一些 * locale * 依赖性。例如:"在" C "区域设置中,isalpha
仅对isupper
或islower
为true的字符返回true。" C17dr § www.example.com 27.4.1.2 2这主要影响非ASCII(0 - 127)范围的字符。当为特定协议进行标记化时,请记住
is...()
函数有 * locale * 变量。wz3gfoph2#
使用
switch
中的case
表示专用字符,使用default:
标签表示范围:或者有点不寻常
mbyulnm03#
我想问一下,是否有一种更简洁的方式来使用大小写匹配a-z和A-Z。
是的,有。
可以简化为:
isalpha()
检查字母字符,如果字符c属于测试类,则返回非零值,否则返回零值。对于其余的符号,可以使用-preferred-
switch()
语句,或者使用if/else
梯形图,ctype.h
中声明的函数可以帮助简化事情。正如@Mike所评论的,GCC提供了一个有用的扩展:Case Ranges (Using the GNU Compiler Collection (GCC)).
也可以在这里看到@Toby的答案,看看discrepancy between the two solutions。
b5buobof4#
我喜欢chux使用查找表的方法,在下面的源代码中,这是
swchux
。它产生:
然后,4-5:
这对于数量有限的
case
语句来说确实很快。但是,如果
case
语句的数量较大,则cmp/jxx
条目会占用大量时间。我遇到过一个
switch/case
块有一百个左右的条目的情况,所以它不能扩展。通过使用计算的后藤(使用
&&label
),我们可以将其简化为(在swfix1
中):对于我的用例,使用计算的后藤而不是
switch
将总体性能提高了30%。使用一些
cpp
宏,我们可以使语法类似于switch/case
块。在上面的例子中,我们使用的是
unsigned char
查找,如果我们使用直接标签表,我们可以减少一条指令(在swfix2
中):这样就省去了一条asm指令,代价是查找表使用8字节/条目(而上面的查找表使用1字节)。
下面是上述示例的
.c
源代码。注意,这里我只是使用
DOIT
宏作为case
中实际代码的占位符,在真实的代码中,每个case
都有自己的/不同的代码。以下是使用
-S
构建的源代码:jk9hmnmh5#
我想问一下,是否有更简洁的方法使用大小写来匹配a-z和A-Z
GCC具有扩展名:
当然,它不能使用非GCC系列编译器进行编译。