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

C 为什么我从只打印17个字节的数组的内容中得到这个输出?,c,cs50,C,Cs50,我正在通过edX上的CS50进行工作,遇到了一个问题,您必须对信用卡号码进行校验和。我是编程新手,甚至比C更新 我正在收集数组中的数字,以便对它们进行操作。 我从原始数字中每隔收集一个数字,然后乘以2 当我试着打印这个集合时,我得到了我最初想要的数字,但随后是一个破折号和一大堆其他数字——我不知道这些数字是从哪里来的 // establishing another array to collect the doubled digits of every other digit from the

我正在通过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位数字是正确的,也是我想要的数字-但是这些其他数字从何而来?

您获得此输出是因为以下两个原因之一:要么您访问的收集器数组超出其界限,要么您无法初始化该数组的最后几个成员,导致垃圾数据被访问

// 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);
您的算法假设收集器和doubledDigs具有相同数量的成员,但由于您的代码不包含声明该数组的部分,因此不清楚这是否正确

假设它们的大小相同,如果您用输入1234567890123填充收集器,则会留下3个未初始化的成员。在C语言中,如果没有显式设置变量或数组成员的值,则其初始值等于内存中该特定位置上发生的任何值。对于有符号整数,可以是2147483647到-2147483648之间的任意值

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


这只解决了收集器和doubledDigs大小相同的情况。例如,如果打算让收集器有14个成员,doubledDigs有16个成员,则必须重新访问循环逻辑。在该示例中,在循环的最后2次迭代中,您将尝试访问收集器的第15个和第16个成员,这些成员不存在。C不会阻止你这样做,但结果充其量是未定义的行为。

旁白:在a=floora/10;你是否意识到a/10是一个整数除法?因此,永远不会有任何小数部分可以丢弃。在同一个数组中使用两个幻数是有悖常理的。首先是int-doubledDigs[16];接着我感谢你的指点。