数组索引减去C中的字符意味着什么?

时间:2016-04-01 21:32:25

标签: c arrays char

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


int calculate(char *target, char *data)
{
    int count = 0;

    char letters[26];

    for (int i = 0; i < 26; ++i)
    {
        letters[i] = '\0';  //same as java ''
        printf("%d : %c\n", i, letters[i] );
        /* code */
    }

    for (int i = 0; i < target[i]; ++i)
    {

        letters[target[i] - 'A'] = target[i];
        printf("%d : %c\n",i,target[i] );

        /* code */
    }

    for (int i = 0; i < data[i]; ++i)
    {
        if(letters[data[i] - 'A'])
        {
            count++;
        }
        /* code */
    }
    return count;
}

int main(int argc, char const *argv[])
{
    int result;
    /* code */
    char target[20];
    char data[20];
    printf("Enter the data\n");
    scanf("%s", data);
    printf("Enter the target\n");
    scanf("%s", target);

    result = calculate(target,data);

    printf("%d\n",result );

    return 0;
}

此示例程序的主要目的是检查数据中的类似单词并添加它们的出现次数。 例如

Target --> DOG
data --> GOAT
  

结果将等于2,因为O&amp; G在数据中出现一次并将它们加起来得到2

我的问题是,当它到达第二个和第三个for循环时,我几乎不明白在target[i] - 'A'的循环内部发生了什么,除了目标索引被分配给字母

对于减去字符的数组索引或者这里的用途是什么意思?

3 个答案:

答案 0 :(得分:3)

数组索引是您放在下标运算符中的东西([]),因此i是数组索引。 target[i]是数组对象元素的下标名称 - 它计算元素,而不是索引。

所有这一切,target是一个字符数组,因此target[i]是一个字符,如您所知,'A'也是一个字符。减去两个字符有类似的语义来减去两个整数:它给出了它们在字符集空间中的区别。在这种情况下,它会告诉您特定角色与角色'A'的距离。假设字母是连续的字符集,'A' - 'A'将是0'B' - 'A'将是1'C' - 'A'将是2,所以上。基本上,该减法将字符'A'映射到数字0,将字符'B'映射到数字1,将字符'C'映射到数字{{1等等。

2数组可能有一个英文字母的每个字母的插槽,其中有关字符letters的一些信息存储在索引'A',有关字符的信息{{1存储在索引0,依此类推。前面描述的映射有助于找到字母表中每个字母的索引,以便程序可以在该数组的相应插槽中读取或写入有关该字符的信息。

答案 1 :(得分:3)

减去A会使用ASCII字符集将A映射到0,将B映射到1等。

由于基于C的数组索引为零,因此有效地允许使用大写字母来确定数组元素的索引。

由于此方法假设字母AZ在字符集中是连续的,因此存在限制。这种假设适用于ASCII,但也有真实的,标准化的字符集,这是不正确的,以及使用这些字符集的真实C编译器。

答案 2 :(得分:2)

你用字母[]做的事情是模糊的。

提到并考虑到目标[i]&amp; 'A'是减去它们的字符就像减去它们的ASCII代码通讯员一样。实质上,与

target[i] - 'A'

你得到了两个字符之间的区别,很明显你正试图在letters数组的索引中使用这种差异。例如,如果target [i]为'C',则执行'C'-'A'会给你2,因为数组索引从零开始,索引2实际上指向数组中的第3个字符。

此外,由于上述原因,您的程序很可能会出现故障,因为如果您为target字符串输入类似“Tiago Rodriguez”的内容,您将遇到堆栈溢出,因为{{ 1}}是105并且执行i将给你40 - 即105 - 65 - 作为结果但是你只为target[i] - 'A'分配了26个字节(假设char是1个字节)。

此外,使用letters输入字符串有三个原因是危险的 -

  1. 它仅将值存储在空间中。
  2. 输入缓冲区的其余部分用于下一个scanf语句。
  3. 它没有检查缓冲区溢出的机制。
  4. 例如,如果您为scanf输入“Tiago Rodriguez”,则“Tiago”将存储在data中,“Rodriguez”将存储在data

    您可以使用target替换scanf。例如:

    fgets
    上面的

    printf("Enter data "); fgets(data,20,stdin); 允许您存储多达19个字符 - 包括空格和换行符 - 而fgets是标准输入的文件描述符。有关fgets的更多信息,请查看this