2

我对 C 非常陌生。如果有人能帮助理解为什么第 13,14 和 16 行中的代码不起作用,但第 17-20 行起作用,我将不胜感激。

使用第一个选项(第 13、14 和 16 行)我得到错误

error: initializer element is not constant

这是什么意思?另外,这是否意味着不能使用某种类型的变量来生成新变量?

谢谢你。

// Define structure for a good
  5 struct good {
  6     char goodname;
  7     double p; //starting proportion
  8     int theta; //average utility
  9     int sigma; //variance of error
 10 };
 11
 12 // The goods H and L
 13 struct good H = {.goodname = 'H', .p = 0.5, .theta = 100, .sigma = 20};
 14 struct good L = {.goodname = 'L', .p = 0.5, .theta = 75, .sigma = 20};
 15
 16 struct good goods[2] = {H, L}; // **Does not work**

 // ** Works**
 17 struct good goods[2] = {
 18     {.goodname = 'H', .p = 0.5, .theta = 100, .sigma = 20},
 19     {.goodname = 'L', .p = 0.5, .theta = 75, .sigma = 20}
 20 };
4

5 回答 5

4

第 16 行不起作用的原因与这个更简单的示例不起作用的原因相同:

const int a = 5;
int b = a; // Does not work: "initializer element is not constant"

这意味着您只需要在初始化程序中使用编译时常量表达式。C 不考虑变量编译时常量,即使是const那些(另一方面,C++ 考虑const变量编译时常量)。

于 2013-08-28T18:08:58.267 回答
2

If the object is static "goods[0]/goods[1]", you can only initialize with constants. So, the reason you did not get an error initializing "good H".

If you define your variable as non-static, (for e..g, in your main() or in any of your function()) you will not get this error, as the object will be treated as "auto".

于 2013-08-28T19:17:31.643 回答
2

这意味着在 C 中您只能使用常量表达式来初始化具有静态存储持续时间的数组或结构。

在您的示例中,所有对象都具有静态存储持续时间,但是:

 struct good H = {.goodname = 'H', .p = 0.5, .theta = 100, .sigma = 20};

上面的初始化器是文字,文字是C中的常量表达式,所以没关系。

 struct good goods[2] = {H, L};

但是这里HL对象不是常量表达式,所以编译器会给你一个错误。

C 对什么是常量表达式有一个相当严格的定义,并且对象的值不被视为常量表达式(即使对象是const用文字限定或初始化的)。

于 2013-08-28T18:08:50.090 回答
2

变量的值,即使变量已经全局初始化为1(并且即使它是const-qualified),它本身也不是常量表达式。

指向静态持续时间变量2的指针是“扩展常量表达式”,可用于初始化指针变量,因此您可以这样做:

struct good *goods[2] = {&H, &L};

例如,如果这适合问题。


1是的,我知道“全局初始化”的定义并不明确。:-) 我的意思是,如果它是一个已初始化的静态持续时间变量,并且在新的初始化程序处可见。

2即任何“全局”(文件范围)变量,或static块内的变量。

于 2013-08-28T18:09:34.503 回答
2

H 和 L 是包含数据的存储位置。该声明:

 struct good goods[2] = {H, L}; // **Does not work**

意味着货物应该指向 H 和 L,或者包含与 H 和 L 相同的值。

或者,将数据从 H 和 L 复制到 goods[0] 和 [1] 或将货物修改为指针数组,如下所示:

 struct good *goods[2];

 goods[0] = &H;
 goods[1] = &L;
于 2013-08-28T18:12:05.387 回答