为什么我从打印只有17个字节的数组内容中得到此输出?

时间:2017-04-12 19:19:45

标签: c cs50

我正在使用edX上的CS50,并且遇到了你必须对信用卡号码进行校验和的问题。我是编程的新手,甚至是C的新手。

我正在收集数组中的数字,以便我可以操纵它们。 我从原始数字中收集了所有其他数字,并将其乘以2。

当我尝试打印这个系列时,我得到了我最初想要的数字,然后是一个破折号和其他数字 - 我不知道它们来自哪里?

// establishing another array to collect the doubled digits of every other digit from the first array
int doubledDigs[16];
int k = 0;
// building that array, ensuring to split any multi digit products and add them idnividually
for (int i = 0; i<= 15; i += 2, k++)
{
   int a = collector[i] * 2;
   if (a > 9)
   {
       for (int c=0; c < 2; c++, k++)
       {
           int b = a % 10;
           doubledDigs[k] = b;
           a = floor(a / 10);
       }
   }
   doubledDigs[k] = a;
}
// print doubledDigs to check it is working
for (int i = 0; i <= 15; i++)
{
    int b = doubledDigs[i];
    printf ("%i", b);
}
printf ("\n");

//add all the doubled digits together
int doubledProduct = 0;
for (int i=0; i <= 15; i++)
{
    doubledProduct += doubledDigs[i];
}
//print product to check
printf("%i\n", doubledProduct);

所以如果输入1234567890123作为我的卡号,我会得到62810410010620-74895702432659 -748924334 作为输出。前14个数字是正确的和我想要的 - 但这些其他数字来自哪里?

1 个答案:

答案 0 :(得分:1)

你得到这个输出是因为以下两件事之一:要么你正在从它的边界访问你的collector数组,要么你没有初始化该数组的最后几个成员,导致正在访问垃圾数据。

您的算法假定collectordoubledDigs具有相同数量的成员,但由于您的代码不包含您声明该数组的部分,因此不清楚这是否属实。

假设它们的大小相同,如果您使用输入“1234567890123”填充collector,那么您将留下3个未初始化的成员。在C中,如果没有显式设置变量或数组成员的值,则其初始值等于在该特定位置的内存中发生的任何值。对于签名的int,可以是2,147,483,647和-2,147,483,648之间的任何地方。

为了防范这种情况,您可能要做的第一件事是使用int collector[16] = {0};对数组进行零初始化。

仅在collectordoubledDigs应该是相同大小的情况下才能解决问题。例如,如果collector有14个成员且doubledDigs有16个成员,则必须重新访问循环逻辑。在该示例中,在循环的最后2次迭代中,您将尝试访问不存在的collector的第15和第16个成员。 C不会阻止你这样做,但结果是最好的未定义行为。