使用开关和指针的方式对我来说很奇怪

时间:2015-05-30 15:01:49

标签: c

我试图理解以下代码:

#include <stdio.h>

int main(void)
{
    int counter[5] = {0};
    int *i, c;
    printf("Please enter a string terminated by ENTER key:\n");
    while(i = counter, (c = getchar()) != '\n')
    {
        switch(c)
        {
          default: continue;
          case 'U'+' ': case 'U': ++ i;
          case 'O'+' ': case 'O': ++ i;
          case 'I'+' ': case 'I': ++ i;
          case 'E'+' ': case 'E': ++ i;
          case 'A'+' ': case 'A': ++*i;
        }
    }
    for(c = 0; c < 5; c++)
       printf("counter[%d] = %d\n", c, counter[c]);

    return 0;
}

此代码因以下原因引起我的注意

  • 首先不理解它,因为出现了数组计数器 是元音的数量,没有任何分配。

  • 其次,因为最后一种情况,指针我有一个星号。

  • 第三,因为在每种情况下都有一个&#39; +&#39; &#39 ;.为什么要添加
    每个元音的空间

3 个答案:

答案 0 :(得分:2)

1)在你的循环开始时,&#39; i&#39;被设置为指向数组中的第一个元素&#39; counter&#39;这是因为:

i = counter;

与:

相同
i = &counter[0];

2)因为你没有任何“休息”。语句,当您输入元音时,&#39; i&#39;将递增以指向数组的其中一个元素。例如,如果您输入&#39; O&#39;,指针&#39; i&#39;将增加3次。然后,由于最后一组case语句增加了&#39; i&#39;指向而不是i&#39;本身,其中一个数组元素的值将递增。

3)&#39; A&#39;是ASCII字符0x41,&#39; &#39;是0x20。 &#39; A&#39; +&#39; &#39;与0x41 + 0x20相同,即0x61,与&#39; a&#39;相同。

答案 1 :(得分:1)

代码是故意混淆的。

  • 小写字母写为<Space> + <upper case equivalent>

  • 指针i通过遍历switch而没有break语句而前进到正确的元音。

第一部分是有效的,因为ASCII字符表的组织方式:大写和小写字母的固定差值为32,这也恰好是空格的ASCII值。

第二部分只依赖于C语言的规则:

  1. 当循环看到元音时,它从适当的开关标签开始并“通过”,执行所有后续的可执行语句。

  2. 除非元音是Aa,否则指针i会增加一次或多次,因此它指向counter[1],{{ 1}}等等

  3. 最终语句counter[2]增加指针++*i现在指向的。这就是元音被计算的地方。例如,如果i增加了两倍,则它指向i,这就是counter[2]递增的内容。

答案 2 :(得分:0)

了解定义声明。阵列定义明确。尽管初始化器是自动变量的扩展,例如自动变量。 gcc支持。

对于这些案例,我解开了一点:

   switch ( c ) {
      default: continue;
      case 'U'+' ':  // 'u' 
      case 'U': ++ i;
      case 'O'+' ':  // 'o'
      case 'O': ++ i;
      ...
   }

这只是一个检查'u''U'的破损版本。因为它依赖于ASCII编码而破碎,其中' '的小数索引为32,小写字母的索引32大于大写字母。看起来有点混淆了我,我不推荐它(出于两个原因)。

如果交换机出现问题:请记住&#34; case标签&#34;故意调用:代码从每个标签执行,直到语句结束。因此,对于'U',i(指针的名称错误; i与整数类型/索引最相关)增加4次 - 这将指向数组!最后一个标签只增加相应的计数器(注意附加的*

我认为对于偶尔的读者来说,代码很难阅读。我不会在没有绝对性能需求的情况下编写这样的内容(而由于多次递增,它可能甚至不能很好地执行)。从学生我不会接受。