为什么我通过打印只有 17 个字节的数组内容得到这个输出?
Why am I getting this output from printing the contents of an array with only 17 bytes?
我正在 edX 上研究 CS50,遇到了必须对信用卡进行校验和的问题 numbers.I 是编程的新手,甚至是 C 的新手。
我正在收集数组中的数字,以便我可以对它们进行操作。
我从原始数字中收集了每隔一个数字并将其乘以二。
当我尝试打印这个集合时,我最初得到了我想要的数字,但随后得到了一个破折号和一大堆其他数字 - 我不知道这些是从哪里来的?
// 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
作为 output.The 前 14 位数字是正确的,也是我想要的 - 但所有这些其他数字来自哪里?
你得到这个输出是因为以下两种情况之一:要么你正在访问你的 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 不会阻止你这样做,但结果充其量是未定义的行为。
我正在 edX 上研究 CS50,遇到了必须对信用卡进行校验和的问题 numbers.I 是编程的新手,甚至是 C 的新手。
我正在收集数组中的数字,以便我可以对它们进行操作。 我从原始数字中收集了每隔一个数字并将其乘以二。
当我尝试打印这个集合时,我最初得到了我想要的数字,但随后得到了一个破折号和一大堆其他数字 - 我不知道这些是从哪里来的?
// 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 作为 output.The 前 14 位数字是正确的,也是我想要的 - 但所有这些其他数字来自哪里?
你得到这个输出是因为以下两种情况之一:要么你正在访问你的 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 不会阻止你这样做,但结果充其量是未定义的行为。