不使用函数和if语句,将大写更改为小写,反之亦然

时间:2015-03-19 07:55:16

标签: c performance function if-statement

我在C中遇到问题:

我无法弄清楚如何将大写更改为小写,反之亦然,而不使用if语句,函数,也不更改字母以外的字符。

此问题的解决方案对有限的资源系统非常有用。

4 个答案:

答案 0 :(得分:4)

您可以执行以下操作:

c ^= ((c>='A' && c <= 'Z') || (c>='a' && c <= 'z')) << 5

...但我不确定资源有限的系统比使用&#39;更好。等

答案 1 :(得分:2)

因为&#39; A&#39;是0x41和&#39; a&#39;是0x61,你可以将0x20位异或。

0x61 ^ 0x20 == 0x41  /* a -> A */
0x41 ^ 0x20 == 0x61  /* A -> a */

在完整字符串char *s的循环中(假设它只包含字母):

for (; *s; s++) *s ^= 0x20;

<小时/> 的修改

我们应该只将它应用于信件。 &#39; A&#39;是0x41。 &#39; Z&#39;是0x5A,小写字符只是upper_case_char + 0x20。

所以c & 0xDF始终是角色的大写版本。

混淆测试看起来像这样:

 for (; *s; s++) *s ^= ((*s & 0xDF) >= 0x41 && (*s & 0xDF) <= 0x5A) 
                    ? 0x20 : 0x00;

或同等的,稍微更具可读性:

 for (; *s; s++) *s ^= ((*s & 0xDF) >= 'A' && (*s & 0xDF) <='Z') 
                    ? 0x20 : 0x00;

答案 2 :(得分:1)

怎么样

void changecase (char * s)
{
    for (; *s; s++)
        *s ^= ((*s>='A') && (*s<='Z') || (*s>='a') && (*s<='z'))?32:0;
}

如果您不喜欢三元组或比较运算符:

void changecase (char * s)
{
    for (; *s; s++)
        *s ~= (
               /* check top bits are 0100 or 0110 */
               ((*s & 0xE0 ^ 0x80) - 0x40) & 0x100) &&
               /* not codes 64 or 96 */
               (*s & 0x1f) &&
               /* first 26 from 64 onwards only */
               !(((*s && 0x1f) - 27) & 0x100)
              ) <<5;
}

答案 3 :(得分:0)

最高效的是定义static char conversionTable = {0x00, 0x01, ...}。您只需将A放在a的ASCII列表中,然后将z放在Z的位置。然后转换成:

char original;
char converted;

converted = converionTable[original];

这只需要256字节的内存,转换速度非常快,因为它只不过是一个索引表访问。

理论注释:如果我是对的,C标准不保证使用ASCII作为字符表示。如果情况确实如此,问题仍然可以解决,但会变得更加混乱。表格不起作用。