1

我不明白为什么在初始化为零之后i设置为0正确。array

该程序运行良好,因为我reinitialized value of k必须i。但我不知道为什么i会变成0. 为什么memset()要清除数组或将数组设置为0

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main()
{
    long long int i = 123456789;
    long long int j = 987654321;
    long long int cnt = 0;
    int array[9] ;
    int xyz, k, x, rem, se;
    xyz = 0;

 //   printf("I = %llf", i);
    for (i; (i < j) && (cnt < 100000); i++)
    {
        k = i;
        x = 0;
        for (se = 0; se <= 9; se++)
        {
            array[se] = 0;
        }

/*************************************************/

        i = k;   // Here i becomes zero. Why?

/************************************************/

        //memset(array, 0, 9);   

        while(k != 0)
        {
            rem = k % 10;
            for(se = 0; se <= 9; se++)
            {
                if(rem == array[se])
                {
                    xyz = 1;
                    break;
                }

            }
            if(rem == array[se])
                {
                    xyz = 1;
                    break;
                }
            array[x++] = rem;
            k = k / 10;
        }
        if (xyz != 1)
        {
            cnt++;
        //    printf("Cnt = %d  ", cnt);
        //    printf("The value i is = %lld\n", i);
        //    Sleep(10);
        }
        xyz = 0;
        // printf("The value i is = %lld\n", i);
        // printf("Cnt = %d  \n", cnt);
        fflush(stdin);
    }
    printf("The value i is = %lld \n", i-1);
    return 0;
}
4

3 回答 3

3

你有一个缓冲区溢出;由于缓冲区在堆栈上,它可能被视为堆栈溢出†</sup>的一种形式。

int array[9];    // Elements array[0] .. array[8]
...

for (se = 0; se <= 9; se++)
{
    array[se] = 0;
}

一定k是被额外的 0 覆盖;i赋值为 0,因为这是k. 当您在数组边界之外写入时,您会调用“未定义的行为”,就像您在此处所做的那样。未定义的行为意味着任何事情都可能发生并且没关系。有时,它似乎会起作用;有时,会有意想不到的副作用。不惜一切代价避免“未定义的行为”。

惯用的for循环是:

for (se = 0; se < 9; se++)
    array[se] = 0;

请注意,<而不是<=.

†</sup>有些人不同意。见评论。


您还询问(已注释掉)调用memset()

//memset(array, 0, 9);

第三个参数 tomemset()是要设置的内存区域的大小(以字节为单位)。您在数组中总共(可能)36 个字节中设置了 9 个字节,这不太可能是您想要的。

在这里,数组是在同一个函数中定义的,所以写起来是安全且明智的:

memset(array, 0, sizeof(array));

如果array是传递给函数的参数,那将无法正常工作;你需要一个不同的尺寸。例如:

void somefunc(int array[], int num)
{
    ...
    memset(array, 0, num * sizeof(array[0]));
    ...
}
于 2012-06-05T10:15:38.600 回答
2

您正在覆盖数组的末尾。

int array[9] ;

for(se = 0; se <= 9; se++)
{
    array[se] = 0;
}

在 C 中,数组是从 0 开始索引的,所以循环往前走一步。惯用的语法是:

for(se = 0; se < 9; se++)

换句话说,使用<元素的数量作为值。通常用来删除可怕的数字常量,如下所示:

for(se = 0; se < sizeof array / sizeof *array; se++)

这使用sizeof运算符自动(在编译时)计算正确的元素数量,因此如果您更改array定义,循环仍然是正确的。

于 2012-06-05T10:14:52.757 回答
1

检查这一点的一种方法是通过打印&x&array[9]来检查 x 和 array[9] 的指针。

如果它们相同,那么您肯定会如上所述覆盖。

于 2012-06-05T14:02:40.133 回答