C 在不使用函数和if语句的情况下,将大写改为小写,反之亦然
我在C语言中遇到了一个问题: 如果不使用if语句、函数,不改变字母以外的字符,我就不知道如何将大写字母改为小写字母,反之亦然C 在不使用函数和if语句的情况下,将大写改为小写,反之亦然,c,performance,function,if-statement,C,Performance,Function,If Statement,我在C语言中遇到了一个问题: 如果不使用if语句、函数,不改变字母以外的字符,我就不知道如何将大写字母改为小写字母,反之亦然 此问题的解决方案对于资源有限的系统非常有用。您可以执行以下操作: c ^= ((c>='A' && c <= 'Z') || (c>='a' && c <= 'z')) << 5 c^=((c>='A'和&c='A'和&c void changecase (char * s) { for (;
此问题的解决方案对于资源有限的系统非常有用。您可以执行以下操作:
c ^= ((c>='A' && c <= 'Z') || (c>='a' && c <= 'z')) << 5
c^=((c>='A'和&c='A'和&c
void changecase (char * s)
{
for (; *s; s++)
*s ^= ((*s>='A') && (*s<='Z') || (*s>='a') && (*s<='z'))?32:0;
}
void changecase(char*s)
{
对于(;*s;s++)
*因为“A”是0x41,“A”是0x61,所以可以对位0x20进行异或运算
0x61 ^ 0x20 == 0x41 /* a -> A */
0x41 ^ 0x20 == 0x61 /* A -> a */
在完整字符串char*s
的循环中(假设它只包含字母):
编辑
我们应该只将其应用于字母。“A”是0x41。“Z”是0x5A,小写字符只是大写字符+0x20
因此c&0xDF
始终是字符的大写版本
模糊测试如下所示:
for (; *s; s++) *s ^= ((*s & 0xDF) >= 0x41 && (*s & 0xDF) <= 0x5A)
? 0x20 : 0x00;
对于(;*s;s++)*s^=(*s&0xDF)>=0x41&(*s&0xDF)='A'&(*s&0xDF)最有效的方法是定义一个静态字符转换表={0x00,0x01,…}
。只需将A
放置在A
的ASCII列表点,……最后将z
放置在z
的点中。然后转换为:
char original;
char converted;
converted = converionTable[original];
这只需要256字节的内存,而且转换非常快,因为它只不过是一个索引表访问
理论提示:如果我是对的,C标准不保证使用ASCII作为字符表示。如果确实是这样,问题仍然可以解决,但会变得更糟。一张表不起作用。有许多可能的解决方案-到目前为止您尝试了什么?有限资源系统是如此有限以至于它甚至不能运行一个if
语句?我认为这是一个家庭作业或面试问题。旨在考虑ASCII和十六进制表示以及位运算。DrKoch-在C语言的基础课程中,这个问题的解决方案被标记为可能对µC有用。可以提出一个论点,即三进制是等效的对于if语句,但可以提出更有力的论点,认为这个问题很愚蠢。@RetiredInja OK,所以我修正了这个问题,并使其更难:-)很好的解释。但是,这些问题要求排除非字母。((c>='A'&&c='A'&&c您假设布尔表达式在为真时转换为整数1,在为假时转换为整数0。这个假设正确吗?这不是未定义的吗?@chmike:是的,这是由c标准保证的。我还假设字符集是ASCII,这不是由标准保证的-但如果系统资源如此有限,则如果
,它就不能负担一个,假设一个特定的字符集可能是合理的:-)我没有见过像tab=[1,2,3,…]这样的表?我只见过像这个tab={1,2,3,…}这样的表。是的,我在使用ASCII。@Arlic我犯了一个错误,当然是{1,2,3,…}
初始化数组。您认为此解决方案如何?
for (; *s; s++) *s ^= ((*s & 0xDF) >= 0x41 && (*s & 0xDF) <= 0x5A)
? 0x20 : 0x00;
for (; *s; s++) *s ^= ((*s & 0xDF) >= 'A' && (*s & 0xDF) <='Z')
? 0x20 : 0x00;
char original;
char converted;
converted = converionTable[original];