1

我尝试了这个 Armstrong 程序,但发现自己被这个空数组的东西纠缠了。这个程序的工作一直困扰着我一段时间,但似乎仍然无法弄清楚这里有什么问题。是的,所以只是想问一个空或不完整数组的元素分配给什么值?它是 NULL 字符,即'\0'吗?我尝试在一个在线 C 编译器上检查它,这个断言似乎是正确的,但 GCC 告诉我们相反。我尝试了这种解决 Armstrong 问题的方法,这是我的代码:

#include <stdio.h>
#include <math.h>

int main()
{
    int num,i,cub,j;
    i = cub = 0;
    int sto[20];
    scanf("%d",&num);
    j = num;
    while(num != 0) 
    {
        sto[i] = num%10;
        num = num / 10;
        i++;
    }
    i = 0;
    while(sto[i] != '\0')
    {
       cub += pow(sto[i],3);
       i++;
    }
    num = j;
    printf("cub: %d     num: %d\n\n",cub,num);
    if(j == cub)
      printf("The number is an Armstrong number");
    else 
      printf("The number is not an Armstrong number");

    return 0;
}

我知道这个问题还有其他方法,但我正在寻找的是上述问题的答案。

4

5 回答 5

2

该数组中的值将是未定义的。它们可能为零,它们可能是从上次使用堆栈的该部分时发生的任何值。同样的原理也适用于堆内存。

于 2021-09-14T19:12:09.600 回答
2

所以只是想问一个空或不完整数组的元素分配给什么值?它是 NULL 字符,即'\0'吗?

不,当你在这里所做的那样在函数体中声明时(即没有初始化器),内容是未定义的。在实践中,这些值将是任何随机数据碰巧最后一次出现在这些位置的堆栈中。当像您在此处所做的那样声明“自动”数组时,编译器只需插入一个堆栈增量以保留空间,但不执行其他任何操作。它可能为零,但可能不是。

于 2021-09-14T19:12:25.463 回答
1

的初始值sto不确定的——它们几乎可以是任何东西,并且每次运行该代码时它们都可能不同。

如果要确保所有元素都包含特定值,您可以:

  • 显式初始化所有 20 个元素;
  • 显式初始化一些元素,其余元素隐式初始化为0;
  • 使用关键字声明数组static以隐式初始化所有元素0(尽管这会改变数组的分配和存储方式);

如果您希望所有元素最初都是0,您可以执行以下操作之一:

int sto[20] = {0}; // explicitly initializes first element to 0, implicitly 
                   // initializes remaining elements to 0

static int sto[20]; // implicitly initializes all elements to 0, *but*
                    // changes how sto is stored

如果您希望将所有元素初始化为 以外的其他内容0,那么您需要显式初始化所有元素:

int sto[20] = {-1, -1, -1, -1, -1, ... };

或使用循环:

for ( size_t i = 0; i < 20; i++ )
  sto[i] = -1; // or whatever initial value
于 2021-09-14T21:28:15.077 回答
1

C没有结束标记,程序员应该处理它。参考这个链接:C语言中的数组结束

建议:在数组中添加一个结束标记,例如,在数组末尾插入“x”,然后循环直到找到标记。或者只使用此代码中的计数器变量。

 #include <stdio.h>
    #include <math.h>
    
    int main()
    {
        int num,i,cub,j;
        i = cub = 0;
        int sto[20];
        scanf("%d",&num);
        j = num;
        while(num != 0) 
        {
            sto[i] = num%10;
            num = num / 10;
            i++;
        }
        int counter = 0;
        while(counter < i)
        {
           cub += pow(sto[counter],3);
           counter++;
        }
        num = j;
        printf("cub: %d     num: %d\n\n",cub,num);
        if(j == cub)
          printf("The number is an Armstrong number");
        else 
          printf("The number is not an Armstrong number");
    
        return 0;
    }

我希望这回答了你的问题。

于 2021-09-14T19:47:44.227 回答
1

您已在没有存储说明符的块范围内声明了一个数组static

int sto[20];

这样的数组具有自动存储持续时间。也就是说,它在退出定义它的块后将不再存在。

如果您要在文件范围内声明数组,例如在函数 main 之前或static在块中使用存储说明符,它将具有静态存储持续时间。

来自 C 标准(6.7.9 初始化)

10如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。如果具有静态或线程存储持续时间的对象未显式初始化,则:

— 如果它具有指针类型,则将其初始化为空指针;

— 如果它具有算术类型,则将其初始化为(正或无符号)零;

— 如果是聚合,则每个成员都根据这些规则(递归地)初始化,并且任何填充都被初始化为零位;

— 如果是联合,则根据这些规则(递归)初始化第一个命名成员,并将任何填充初始化为零位;

于 2021-09-14T19:40:51.283 回答