【问题标题】:C: Do I have to initialize arrays used within a function?C:我必须初始化函数中使用的数组吗?
【发布时间】:2021-09-13 20:27:40
【问题描述】:

在调试我的程序时,我注意到我的二维数组的一些元素包含非零值。

float Ak[2][2];
Ak[0][0] = 1;
Ak[1][1] = 1;

当我运行此代码时,Ak[0][0]Ak[1][1] 按预期为 1,但 Ak[0][1] 为 1.081,我实际上预计为 0。

这可能是因为数组没有被隐式初始化。但总是这样吗?当我想要特定行为时,我是否总是必须初始化我的数组,或者在某些情况下编译器会自动执行此操作?是否依赖于编译器?

还有一个几乎最重要的问题:这种行为是在哪里指定的? (我的论文需要引用)

【问题讨论】:

  • 局部变量没有任何默认初始化。它们开始时包含 0 的可能性与任何其他看似随机的值一样。这适用于数组和普通变量。您可以阅读不同类变量的初始化规则摘要here
  • 本地非静态变量未初始化。局部静态变量被隐式初始化为零,就像非局部变量一样。

标签: arrays c initialization


【解决方案1】:

具有自动存储持续时间的变量(在块范围内声明的变量)不会被隐式初始化。

具有静态存储持续时间的变量(在文件范围内声明的变量或具有说明符 static 的变量)如果未初始化显式隐式初始化(​​对于算术类型,它们被零初始化,或者对于指针类型,它们被初始化为空指针) .

您似乎在函数中声明了数组

float Ak[2][2];
Ak[0][0] = 1;
Ak[1][1] = 1;

所以它的元素不会被隐式初始化。

你可以写例如

float Ak[2][2] =
{
    [0][0] = 1.0f, [1][1] = 1.0f 
};

在这种情况下,数组的所有元素都将被初始化。没有显式初始化器的元素将被初始化为零。

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    float Ak[2][2] =
    {
        [0][0] = 1.0f, [1][1] = 1.0f 
    };

    printf( "Ak[0][0] = %f, Ak[0][1] %f, Ak[1][1] = %f\n", 
             Ak[0][0], Ak[0][1], Ak[1][1] );
    
    return 0;
}

程序输出是

Ak[0][0] = 1.000000, Ak[0][1] 0.000000, Ak[1][1] = 1.000000

或者,您也可以通过以下方式初始化数组

float Ak[2][2] =
{
    [0] = { [0] = 1.0f }, [1] = { [1] = 1.0f } 
};

【讨论】:

    【解决方案2】:

    在本地定义的不是static 的任何变量(不仅仅是数组),或更正式地说是那些具有自动存储持续时间 的变量,都不会被隐式初始化。在文件范围或static 定义的那些,即具有静态存储持续时间 的那些,被隐式初始化为 0 或 NULL。

    这在C standard 的第 6.7.9p10 节中有详细说明:

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

    • 如果有指针类型,则初始化为空指针;
    • 如果它具有算术类型,则将其初始化为(正或无符号)零;
    • 如果是聚合,则每个成员都根据这些规则(递归)初始化,并且任何填充都初始化为零位;
    • 如果是联合,则根据这些规则(递归)初始化第一个命名成员,并初始化任何填充 零位;

    当然,一个未初始化的变量恰好为 0 并不意味着它不包含垃圾。

    【讨论】:

    • 另外,恰好是0并不代表就是0! Indeterminate 意味着它可能是 3,即使它被视为 0。
    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多