我试图理解以下代码:
#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 ;.为什么要添加
每个元音的空间
答案 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语言的规则:
当循环看到元音时,它从适当的开关标签开始并“通过”,执行所有后续的可执行语句。
除非元音是A
或a
,否则指针i
会增加一次或多次,因此它指向counter[1]
,{{ 1}}等等
最终语句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次 - 这将指向数组!最后一个标签只增加相应的计数器(注意附加的*
。
我认为对于偶尔的读者来说,代码很难阅读。我不会在没有绝对性能需求的情况下编写这样的内容(而由于多次递增,它可能甚至不能很好地执行)。从学生我不会接受。