不理解这个陌生的语法:arr1[ arr2[i] - 'a' ]++
Don't understand this unfamiliar syntax: arr1[ arr2[i] - 'a' ]++
我正在查看一个程序,它可以找到输入字符串的频率。比较是根据字符串的 ASCII 值与小写字母 'a' 的 ASCII 值进行的。我已经实施了;它可以工作,尽管有一个错误,但本质上,我不知道特定的代码行;
for (int i = 0; i < strlen(arr2); i++)
{
// this line...
arr1[ arr2[i] - 'a' ]++;
}
arr1 是 arr1[26] = {0}
,
也就是说,字母表中的所有字母都被分配了一个索引,数组被初始化为零,而 arr2[]
作为函数参数,接收标准输入。
神秘的代码行是如何工作的,它在说什么?
完整代码:
#include <stdio.h>
#include <string.h>
#define ALEPH 26
void freq(char arr2[]);
int main ()
{
char * str;
printf("\nCharacter Frequency\n"
"--------------------\n");
// user input
printf("\nEnter a string of characters:\n");
fgets(str, ALEPH, stdin);
freq(str);
return 0;
}
// Function Definiton
void freq (char arr2[])
{
// array for ascii characters initialised to 0
int arr1[ALEPH] = {0};
// scan and cycle through the input array
for (int i = 0; i < strlen(arr2); i++)
{
arr1[ arr2[i] - 'a' ]++;
}
for (int j = 0; j < 26; j++)
{
if ( arr1[j] != 0 )
{
printf("\nCharacter: %c - Frequency: %d", 'a'+j, arr1[j]);
}
}
printf("\n");
}
你问的线路:
arr1[ arr2[i] - 'a' ]++;
这一行:
- arr1是将累加直方图的数组
- arr2 是将有助于直方图的输入字符串
- i 是输入字符串的索引。
这可以重写为:
ch = arr2[i];
histogram_slot = ch - 'a';
arr1[histogram_slot ] = arr1[histogram_slot ] + 1;
对于输入字符串中的每个字符,从字符串中提取字符并分配给“ch”。 “ch”通过减去'a'转换为直方图数组中的索引。在第三行,histogram_slot 加一。 histogram_slot 'a' 递增 0,'b' 递增 1,'c' 递增 2,...,'z'.
递增 25
此代码中的一个严重错误是它仅适用于小写字母。大写字母、数字、标点符号、Unicode、扩展 ASCII 或不在 'a' 和 'z' 之间的任何字符都会写入意外的内存区域。充其量,这将导致意外崩溃。在中等灾难中,它会导致通过您的测试的偶发故障。在最坏的情况下,它会创建一个安全漏洞,允许某人不受控制地访问您的堆栈,从而接管线程的执行。
arr1
是26个int
的数组,初始化为0
。其元素的索引为0..25
.
arr2
被假定为仅由小写字母 'a'..'z'
组成的字符串。假设这些字符使用一种编码,其中小写字母是单字节且值是连续的,例如 ASCII(其中 a=97
,...,z=122
)。与这些假设不匹配的任何其他内容都将导致此代码中出现 未定义的行为。
代码循环遍历arr2
,对于每个字符,通过从字符的数值中减去'a'
(即ASCII 97
)的数值来计算索引:
'a' - 'a'
= 97 - 97
= 0
'b' - 'a'
= 98 - 97
= 1
...
'z' - 'a'
= 122 - 97
= 25
然后代码访问该索引处的 arr1
元素,并将该元素的值递增 1。
我正在查看一个程序,它可以找到输入字符串的频率。比较是根据字符串的 ASCII 值与小写字母 'a' 的 ASCII 值进行的。我已经实施了;它可以工作,尽管有一个错误,但本质上,我不知道特定的代码行;
for (int i = 0; i < strlen(arr2); i++)
{
// this line...
arr1[ arr2[i] - 'a' ]++;
}
arr1 是 arr1[26] = {0}
,
也就是说,字母表中的所有字母都被分配了一个索引,数组被初始化为零,而 arr2[]
作为函数参数,接收标准输入。
神秘的代码行是如何工作的,它在说什么?
完整代码:
#include <stdio.h>
#include <string.h>
#define ALEPH 26
void freq(char arr2[]);
int main ()
{
char * str;
printf("\nCharacter Frequency\n"
"--------------------\n");
// user input
printf("\nEnter a string of characters:\n");
fgets(str, ALEPH, stdin);
freq(str);
return 0;
}
// Function Definiton
void freq (char arr2[])
{
// array for ascii characters initialised to 0
int arr1[ALEPH] = {0};
// scan and cycle through the input array
for (int i = 0; i < strlen(arr2); i++)
{
arr1[ arr2[i] - 'a' ]++;
}
for (int j = 0; j < 26; j++)
{
if ( arr1[j] != 0 )
{
printf("\nCharacter: %c - Frequency: %d", 'a'+j, arr1[j]);
}
}
printf("\n");
}
你问的线路:
arr1[ arr2[i] - 'a' ]++;
这一行:
- arr1是将累加直方图的数组
- arr2 是将有助于直方图的输入字符串
- i 是输入字符串的索引。
这可以重写为:
ch = arr2[i];
histogram_slot = ch - 'a';
arr1[histogram_slot ] = arr1[histogram_slot ] + 1;
对于输入字符串中的每个字符,从字符串中提取字符并分配给“ch”。 “ch”通过减去'a'转换为直方图数组中的索引。在第三行,histogram_slot 加一。 histogram_slot 'a' 递增 0,'b' 递增 1,'c' 递增 2,...,'z'.
递增 25此代码中的一个严重错误是它仅适用于小写字母。大写字母、数字、标点符号、Unicode、扩展 ASCII 或不在 'a' 和 'z' 之间的任何字符都会写入意外的内存区域。充其量,这将导致意外崩溃。在中等灾难中,它会导致通过您的测试的偶发故障。在最坏的情况下,它会创建一个安全漏洞,允许某人不受控制地访问您的堆栈,从而接管线程的执行。
arr1
是26个int
的数组,初始化为0
。其元素的索引为0..25
.
arr2
被假定为仅由小写字母 'a'..'z'
组成的字符串。假设这些字符使用一种编码,其中小写字母是单字节且值是连续的,例如 ASCII(其中 a=97
,...,z=122
)。与这些假设不匹配的任何其他内容都将导致此代码中出现 未定义的行为。
代码循环遍历arr2
,对于每个字符,通过从字符的数值中减去'a'
(即ASCII 97
)的数值来计算索引:
'a' - 'a'
= 97 - 97
= 0
'b' - 'a'
= 98 - 97
= 1
...
'z' - 'a'
= 122 - 97
= 25
然后代码访问该索引处的 arr1
元素,并将该元素的值递增 1。