我正在使用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个数字是正确的和我想要的 - 但这些其他数字来自哪里?
答案 0 :(得分:1)
你得到这个输出是因为以下两件事之一:要么你正在从它的边界访问你的collector
数组,要么你没有初始化该数组的最后几个成员,导致正在访问垃圾数据。
您的算法假定collector
和doubledDigs
具有相同数量的成员,但由于您的代码不包含您声明该数组的部分,因此不清楚这是否属实。
假设它们的大小相同,如果您使用输入“1234567890123”填充collector
,那么您将留下3个未初始化的成员。在C中,如果没有显式设置变量或数组成员的值,则其初始值等于在该特定位置的内存中发生的任何值。对于签名的int
,可以是2,147,483,647和-2,147,483,648之间的任何地方。
为了防范这种情况,您可能要做的第一件事是使用int collector[16] = {0};
对数组进行零初始化。
仅在collector
和doubledDigs
应该是相同大小的情况下才能解决问题。例如,如果collector
有14个成员且doubledDigs
有16个成员,则必须重新访问循环逻辑。在该示例中,在循环的最后2次迭代中,您将尝试访问不存在的collector
的第15和第16个成员。 C不会阻止你这样做,但结果是最好的未定义行为。