在迭代相同的数组时更改数组值会导致奇怪的行为

时间:2015-04-22 20:15:14

标签: c arrays

我写了一个循环来使用引用数组替换字符串中的每个字符。

for(int i=0 ; i < encoded_message_len ; i++){

    for(int j=0; j < 26 ; j++){

        if(encoded_message_copy[i] == substitution_alphabet[j]){

            printf("%c ->>>> %c @ index:%d \n",encoded_message_copy[i], original_alphabet[j], i);
            encoded_message_copy[i] = original_alphabet[j];
        }
    }
}

然而,当我运行此代码时,我得到一个奇怪的输出:

J ->>>> C @ index:0
H ->>>> R @ index:1
Q ->>>> Y @ index:2
Y ->>>> Z @ index:2
S ->>>> P @ index:3
U ->>>> T @ index:4
T ->>>> V @ index:4
X ->>>> O @ index:6
F ->>>> L @ index:7
L ->>>> X @ index:7
X ->>>> O @ index:8
B ->>>> G @ index:9
G ->>>> W @ index:9
Q ->>>> Y @ index:10
Y ->>>> Z @ index:10

当我从循环中删除此行:encoded_message_copy[i] = original_alphabet[j];时,我得到了预期的输出:

J ->>>> C @ index:0
H ->>>> R @ index:1
Q ->>>> Y @ index:2
S ->>>> P @ index:3
U ->>>> T @ index:4
X ->>>> O @ index:6
F ->>>> L @ index:7
X ->>>> O @ index:8
B ->>>> G @ index:9
Q ->>>> Y @ index:10

有人可以解释为什么会这样吗?

5 个答案:

答案 0 :(得分:1)

在需要移除的行之后放置break;以使其正确(在for循环内)

您更改encoded_message_copy的内容,这可能导致语句if(encoded_message_copy[i] == substitution_alphabet[j])多次匹配i的相同值; - )

答案 1 :(得分:1)

您在同一位置找到了几个符号。 当你找到它时,你需要跳过进一步查看第i个符号。 尝试添加break

if(encoded_message_copy[i] == substitution_alphabet[j]) {
    printf("%c ->>>> %c @ index:%d \n",encoded_message_copy[i], original_alphabet[j], i);
    encoded_message_copy[i] = original_alphabet[j];
    break;
}

答案 2 :(得分:1)

您正在更改数据 - 外部循环的早期迭代会更改您的数据,以便稍后查看。

答案 3 :(得分:1)

问题是当你使用语句

        encoded_message_copy[i] = original_alphabet[j];

你没有打破循环。

for(int j=0; j < 26 ; j++){

    if(encoded_message_copy[i] == substitution_alphabet[j]){

        printf("%c ->>>> %c @ index:%d \n",encoded_message_copy[i], original_alphabet[j], i);
        encoded_message_copy[i] = original_alphabet[j];
    }
}

因此循环继续将新替换字符与substitution_alphabet中的其他字符进行比较。

如果角色已被替换,你应该打破循环

for(int j=0; j < 26 ; j++){

    if(encoded_message_copy[i] == substitution_alphabet[j]){

        printf("%c ->>>> %c @ index:%d \n",encoded_message_copy[i], original_alphabet[j], i);
        encoded_message_copy[i] = original_alphabet[j];
        break;
    }
}

答案 4 :(得分:1)

/* msg_ptr is the position within the encoded message */
/* letter is a numeric value which corresponds to letter of the
   alphabet (0 maps to 'A', 1 => 'B', etc. */
for (int msg_ptr = 0 ; msg_ptr < message_len ; msg_ptr++) {
    for (int letter = 0; letter < 26 ; letter++) {
        if(encoded_message[msg_ptr] == substitution[letter]) {
           encoded_message[msg_ptr] = original[letter];
        }
    }
}

现在问题可能会变得更加清晰。问题是,当您使用encoded_message[msg_ptr]中的值修改original[letter]时,内部循环(字母 for循环)就在执行/增量旁边。这意味着对于未更改的if(i)和递增的msg_ptr(j)值,再次进行letter比较。这意味着使用encoded_message[msg_ptr]处的新解码值进行比较。

成功查找并替换给定位置的编码消息后,您需要前进到encoded_message数组中的下一个字符(即增加msg_ptr(i)的值。这可以使用 break keyword完成。

Another sitebreak(和continue)语句的一些程序执行图,这可能会使它更清晰。

如果您在理解为什么这是必要的(或者换句话说嵌套循环如何操作)时遇到问题,请在头脑中精神上运行以下示例,以及编译器以查看。

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 4; j++) {
        printf("i=%d j=%d\n", i, j);
    }
}

默认情况下,内循环(j)将在外循环(i)的下一个迭代出现之前完成。