6

我目前在一个函数中有一些代码,如下所示:

static const int kFrameCountSample = 250;
static float * samples = (float *)calloc(kFrameCountSample, sizeof(float));

我喜欢将 samples 数组完全清零一次calloc()

我也可以编写代码,以便samples在堆栈上分配。

static const int kFrameCountSample = 250;
static float samples[kFrameCountSample];

但现在samples没有初始化为零值。我将如何在分配时对其进行初始化?

4

4 回答 4

17

为了完整起见(注意:这是 C99 而不是 C++):

重要的是要注意,如果您定义并初始化一个长度k小于k - 1值的静态数组,那么其余部分将被零填充。因此:

static float samples[kFrameCountSample];

... 等同于:

static float samples[kFrameCountSample] = { 0 }; // Zero-fills.

...并且将零填充samples。此外,如果您执行以下操作:

static float samples[kFrameCountSample] = { 1, 2, 3 }; // Zero-fills elements of position 3 ... 250.

...它将零填充初始化中未分配的其余元素samples

评论:

  • 全局变量自动填零(如果这是意图,则不需要初始化)。
  • C99 标准第6.7.8.10节中未初始化静态对象的标准说:

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

  • 如果是指针类型,则初始化为空指针;
  • 如果它具有算术类型,则将其初始化为(正或无符号)零;
  • 如果是聚合,则每个成员都根据这些规则(递归地)初始化;
  • 如果是联合,则根据这些规则(递归地)初始化第一个命名成员。”
于 2013-08-17T00:13:38.390 回答
7

您提供的代码:

static const int kFrameCountSample = 250;
static float samples[kFrameCountSample];

无效 C。具有静态存储持续时间的对象不能具有可变修改类型。另一方面,这将是有效的:

#define kFrameCountSample 250
static float samples[kFrameCountSample];

这在文件范围或函数范围内都有效。在这两种情况下,数组samples都具有静态存储持续时间,这意味着它在程序的整个生命周期中都存在,并且仅在程序启动时初始化一次。唯一的区别是,如果它在函数中,则名称的范围samples仅限于声明它的块。在这两种情况下,它都不可能在堆栈上分配。

samples这里的数组零初始化的 -具有静态存储持续时间的对象永远不会 uninitialized。如果您不提供显式初始值设定项,它们将被初始化为相应类型的零。

如果您确实希望将数组存储在堆栈上 - 也就是说,在输入包含声明的函数时创建并在退出该函数时销毁,C 称为自动存储持续时间- 那么您必须在函数中声明它,省略static关键字并添加一个显式初始化程序:

float samples[kFrameCountSample] = { 0 };

(在这种情况下kFrameCountSample不需要是一个宏,static const int如果你愿意,它可以是一个)。

{ 0 }无论数组大小,单个都可以,因为 C 中的对象永远不会部分初始化 - 如果您初始化数组或结构的任何子对象,其余子对象将被初始化为零的适当类型,就像具有静态存储持续时间的对象。

于 2013-08-17T00:25:27.947 回答
1

仅将某些位置初始化为值的数组将在其余位置为零。

static const int kFrameCOuntSample = 250;
static float samples[kFrameCOuntSample] = { 0 };

应该做的伎俩。

于 2013-08-16T23:59:09.610 回答
0

你可以做 memset 以避免任何东西没有被初始化为零的机会。

static float samples[kFrameCountSample];
memset(samples,0,kFrameCountSample*sizeof(float));

http://man7.org/linux/man-pages/man3/memset.3.html

它所做的是为样本中的每个字节设置一个。这意味着它将被快速初始化为 0。

于 2013-08-17T01:40:38.497 回答