【问题标题】:What is the default value of an element in an array?数组中元素的默认值是多少?
【发布时间】:2021-03-09 02:53:31
【问题描述】:

我目前正在参加哈佛的 CS50x 课程,遇到了以下问题。

在下面的简短摘录中,hashtable[i] 默认设置为 null 吗?我的印象是,当我为 10 个节点(如下所示)分配足够的内存时,我应该得到 10 个不同的地址而不是空指针。但是,我正在学习的课程似乎表明,即使我为 10 个节点分配了足够的内存,也不会立即为它们分配地址。相反,它们将被分配空指针。

typedef struct node
{
    char word[N + 1];
    struct node *next;
}
node;

node *hashtable[10];

【问题讨论】:

  • 你得到十个不同的地址,例如,十个可以存储地址的空格。但它们仍然可以具有相同的,即指向相同的事物(或指向相同的缺失事物,即全部为空)。
  • 当然,指针中存储的地址值也可以只是无效垃圾。但无论如何,指针当然不会指向节点,因为还没有任何节点可供它们指向
  • 不管怎样,教科书对此有什么看法
  • 如何/是否初始化取决于它的声明位置。

标签: arrays c scope initialization cs50


【解决方案1】:

数组的元素是否

node *hashtable[10];

是否由空指针初始化取决于数组的声明位置。

如果数组具有自动存储持续时间,即如果它在函数内的代码块中声明,则其元素未初始化并且具有不确定的值。

如果数组是在文件范围内声明的(在任何函数之外),则它具有静态存储持续时间,并且其元素由空指针初始化。

来自 C 标准(6.7.9 初始化)

10 如果具有自动存储时长的对象未初始化 明确地说,它的值是不确定的。如果一个物体有静电 或者线程存储时长未显式初始化,则:

——如果是指针类型,则初始化为空指针; ...

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

【讨论】:

  • 具有静态存储持续时间且没有初始化器的指针被初始化为空指针,而不是空指针常量。
  • @EricPostpischil 来自 C 标准“如果将空指针常量转换为指针类型,则生成的指针称为空指针”
  • 表示转换后的空指针常量是空指针。它并没有说空指针是空指针常量,无论是否转换。
  • 标准的相关部分是 C17 6.7.9/10 “如果它有指针类型,它被初始化为空指针;”。另见What's the difference between null pointers and NULL?
  • C 标准允许 C 实现具有空指针的多种表示形式。 空指针常量 是源代码中的特定表达式。编译器在没有显式初始化器的情况下用于初始化指针的表示不一定与它用于空指针常量的表示相同。
【解决方案2】:

哈希表数组的初始化取决于它的声明位置和方式。如果 hashtable 在函数之外声明,则每个元素都被初始化为 NULL(本质上没有指向任何内容)。如果 hashtable 在函数内声明并具有存储类 static,这也是正确的。两者唯一的区别是后者只能在函数内部访问。

node *hashtable[10]; /*each element is initialized to NULL*/

void f(void)
{
    static node *hashtable[10]; /*each element is initialized to NULL*/
    ...
}

如果 hashtable 在函数内部声明并且没有存储类静态(即常规局部变量),则每个元素都是未定义的,这实际上意味着它可以具有任何值:

void g(void)
{
    node *hashtable[10]; /*each element is undefined*/
    ...
}

造成这种差异的原因是编译器可以免费初始化程序整个生命周期中存在的变量;变量被编译成可执行文件。另一方面,每次调用函数时都需要初始化一个局部(非静态)变量,因此会产生运行时开销。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 2012-09-26
    • 1970-01-01
    • 2014-10-20
    • 2018-07-12
    • 2015-09-07
    • 1970-01-01
    相关资源
    最近更新 更多