为什么“未签名的int”导致程序崩溃

Why was `unsigned int` causing the program to crash?

本文关键字:程序 崩溃 int 未签名的 为什么      更新时间:2023-10-16

我必须创建一个程序,通过排列字母来检查是否可以从另一个单词中获取两个单词。我编写了代码,如下所示,我花了很长时间努力找出程序崩溃的原因,在某些时候我想将这些变量的基础金属类型从unsigned intunsigned int code = 0, i, j, counter = 0, ok = 1;)更改为integerint code = 0, i, j, counter = 0, ok = 1;),现在它工作正常,但我不知道发生了什么变化,所以现在它可以工作了。我知道(如果我错了,请纠正我)unsigned int从 0(包括 0)变成一个非常大的数字。所有变量都没有低于 0,所以我不知道为什么它在 unsigned int 版本中不起作用,以及基本类型更改如何解决崩溃。

#include<iostream>
#include<string.h>
using namespace std;
int main()
{   char word1[50], word2[50];
    unsigned int code = 0, i, j, counter = 0, ok = 1;
    cout << "Type in the first word and then press ENTER:";
    cin.getline(word1, 50);
    cout << "Type in the second word and then press ENTER:";
    cin.getline(word2, 50);
    cout << endl;
    if (strlen(word1) == strlen(word2)) //If the two words don't have the same lenght, it's impossible to obtain one word of the other by permutating it's letters.
    {   for (i = 0; word1[i]; i++)  /*This nested FOR will generate a number in the code variable. The first digit will indicate how many times will the letter word1[0] be found in word2,
                                    the second digit will indicate how many times will the letter word1[1] be found in word2 and so on until the end of word1*/
        {   counter = 0;
            for (j = 0; word2[j]; j++)
                if (word1[i] == word2[j])
                    counter += 1;
            code = code * 10 + counter;
        }
        i = strlen(word1) - 1;
        while (i >= 0 && ok)    /*In this loop we are checking if the code is valable also for the word1 itself. If it is, it means that the words can be obtained one of the other by permutating the letters*/
        {   counter = 0;        
            for (j = strlen(word1) - 1; j >= 0; j--)
                if (word1[i] == word1[j])
                    counter++;
            if (counter == code % 10)
                ok = 1;
            else
                ok = 0;
            code = code / 10;
            i--;
        }
        if (ok)
            cout << "Yes, the words can be obtained one of the other by permutating the letters.";
        else
            cout << "No, the words can not be obtained one of the other by permutating the letters.";
    }
    else
        cout << "No, the words can not be obtained one of the other by permutating the letters.";
    cin.get();
}

你的部分代码是:

while (i >= 0 && ok) { /* ...stuff here... */  --i; }

对于无符号,如果 i 为 0 并且您递减它,它将成为最大无符号值。 因此,i 始终大于或等于 0,while 循环继续执行。

我的猜测是,这就是正在发生的事情,然后,当您访问word[i]时,您将访问数组的边界之外并崩溃。

问题可能来自以下代码:

for (j = strlen(word1) - 1; j >= 0; j--)

因为您将 j 定义为无符号 int,所以 for 循环会永远持续并且永远不会中断。

初学者错误:考虑一下,如果 i 是一个无符号的 int,i>= 0 将永远为真。它不可能是假的。如果将 i 设置为 0,然后减去 1,您将获得一个非常大的正数。

如果您的编译器没有给您警告,请让某人向您展示如何打开更多警告。