【问题标题】:C Array behaves different with different number of digits, why?C Array 的行为因位数不同而不同,为什么?
【发布时间】:2012-11-15 02:00:03
【问题描述】:

我有一个代码,它从输入中获取一个数字,然后将其放入数组中,然后打印所述数组。但是有一个很奇怪的副作用,当我输入 13 位数字时,我的最后一位数字是错误的。如果我输入 15 或 16 位数字,一切都很好。我无法理解发生了什么!这是代码: numberDigits 是 12、14 或 15,取决于 number 的位数。

int myNumber[numberDigits];
    for (int i = 0; i <= numberDigits; i++)
    {
        myNumber[numberDigits - i] = number % 10;
        number = number / 10;         
    } 
    printf("\n");

    for (int i = 0; i <= numberDigits; i++)

    {
        printf("%i",myNumber[i]);
    }

编辑: 我的号码被初始化为 long long int。这是验证位数的检查:

    if (number / 1000000000000 >= 1 && number / 1000000000000 < 10)
    {
        numberDigits = 12;
    } 
if (number / 100000000000000 >= 1 && number / 100000000000000 < 10)
    {
        numberDigits = 14;
    }
if (number / 1000000000000000 >= 1 && number / 1000000000000000 < 10)
    {
        numberDigits = 15;
    }  

编辑:上次更新,是的,我已经更新了我的代码,并且它按照您的建议按预期工作,但我需要了解为什么我的代码不起作用。我认为也许 array[12] 实际上包含 12 个元素而不是 13,当我用它访问元素 array[12] 时,我从内存中得到了一些随机值,但为什么这不会发生在 array[14] 或 array [15] 分别有 15 位和 16 位数字。以及为什么当您在错误位置访问数组时程序不会崩溃。下面的原始问题带有不起作用的旧代码。

编辑:这里是感兴趣的人的完整列表。

#include <stdio.h>
#include <cs50.h>

int verify (long long int number);

int main(void)

{
    printf("Please enter card number: \n");
    long long int number = GetLongLong();
    // AMEX uses 15 digits
    if (number > 100000000000000 && ((number / 10000000000000 == 34) || (number / 10000000000000 == 37)))
    {        

        printf("AMEX");

    }

    if (number > 1000000000000 && number < 10000000000000 && (number / 1000000000000 == 4))
    {
        printf("VISA");
    }

    if (number > 1000000000000000 && number < 9999999999999999 && (number / 1000000000000000 == 4))
    {
        printf("VISA");
    }

        if (number > 1000000000000000 && number < 9999999999999999 && (number / 100000000000000 == 51 || number / 100000000000000 == 52 || number / 100000000000000 == 53 || number / 100000000000000 == 54 || number / 100000000000000 == 55))
    {
        printf("MASTERCARD");
    }

    return verify(number); 
}



int verify (long long int number)
{
    int numberDigits;
    if (number / 1000000000000 >= 1 && number / 1000000000000 < 10)
        {
            numberDigits = 12;
        } 
    if (number / 100000000000000 >= 1 && number / 100000000000000 < 10)
        {
            numberDigits = 14;
        }
    if (number / 1000000000000000 >= 1 && number / 1000000000000000 < 10)
        {
            numberDigits = 15;
        }       

    int myNumber[numberDigits];
    for (int i = 0; i <= numberDigits; i++)
    {
        myNumber[numberDigits - i] = number % 10;
        number = number / 10;         
    } 
    printf("\n");

    for (int i = 0; i <= numberDigits; i++)

    {
        printf("%i",myNumber[i]);
    }

    return 0;
}

【问题讨论】:

    标签: c cs50


    【解决方案1】:

    您的for 循环应如下所示:

    for (int i = 0; i < numberDigits; i++)
    

    由于索引是从零开始的,所以最后一个是numberDigits - 1。所以&lt;= 会走到最后。

    【讨论】:

    • 如果我这样做,我的第一个数字是零并且是错误的。因为对于 13 位数字,我使用数组 [12],所以我的最后一位数字仍然是 0。
    • 我明白了。是的,需要做更多的工作。但我在处理你的代码时遇到了问题。 number 第一次在哪里初始化?
    • 确实,我得到了正确数字的 0xxxxxxxxxxx,并且缺少最后一个数字。正如我所说,它的工作原理是这样的,首先是零,等等,当 numberDigits 为 12 并且 12 也是数组中的最后一个时结束,所以
    【解决方案2】:

    我觉得应该是这样的:

    for(int i = 0; i < numberDigits; ++i) printf("%d",myNumber[i]);
    

    代替:

    for(int i = 0; i <= numberDigits; ++i) printf("%i",myNumber[i]);
    

    在第一个循环中:

    myNumber[numberDigits - (i + 1)] = number % 10;
    

    此外,您可以使用类似的方法来了解位数:

    int digits(long long num) {
      if(!num) return 1;
      return log10(num) + 1;
    }
    

    【讨论】:

    • 这可行,但我的代码有什么问题?在各个层面上基本相同。为什么尾随数字会发生变化,例如,如果我输入 9837367482735,它会给我 9837367482731,但如果我输入 15 或 16 位数字,则全部正确。
    • 我不知道出了什么问题,但也许你正在做其他事情。把整个代码放上来看看有什么问题。
    • 你应该尝试按照我最初的建议:myNumber[numberDigits - (i + 1)] = number % 10;
    • 是的,我已经更新了我的代码,它按照您的建议按预期工作,但我需要了解为什么我的代码不起作用。我认为也许 array[12] 实际上包含 12 个元素而不是 13,当我用它访问 array[12] 时,我从内存中得到了一些随机值,但是为什么 array[14] 或 array[ 不会发生这种情况15] 分别有 15 位和 16 位数字。以及为什么当您在错误的位置访问数组时程序不会崩溃。
    • 如果您声明这样的数组:int arr[20] 您无法访问索引 20,只能从 0 到 19,这就是为什么在循环中您还要计算数组的长度,其中这种情况是20,它可能会导致一些错误,同时,当你做类似arr[arr.size - i]的事情时,你最终会访问arr[20](当i = 0时)然后再一次,你不能这样做。
    猜你喜欢
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 2014-01-25
    • 1970-01-01
    相关资源
    最近更新 更多