【问题标题】:Can members in a structure be initialized to a value?结构中的成员可以初始化为一个值吗?
【发布时间】:2013-01-06 01:03:47
【问题描述】:

我只是想知道在结构中声明和定义的变量是否可以初始化为某个值,并计划使用函数指针来模仿 OOP 中的类。

示例代码:

typedef struct{
int x;
int (*manipulateX)(int) = &manipulateX;
}x = {0};

void main()
{
    getch();
}

int manipulateX(int x)
{
    x = x + 1;
return x;
}

【问题讨论】:

  • 我不明白你链接中的这部分“直接的答案是因为结构定义声明了一个类型而不是一个可以初始化的变量。你的例子是:struct s { int i=10 ; }; 这没有声明任何变量——它定义了一个类型。要声明一个变量,你可以在 } 和 ; 之间添加一个名称,然后你会在之后初始化它:struct s { int i; } t = { 10 };"
  • 特别是说“要声明一个变量,你会在}和;之间添加一个名称,然后你会初始化它:struct s { int i; } t = { 10 };"
  • 请看我编辑的帖子,添加了一些示例代码

标签: c struct initialization


【解决方案1】:

从C99开始,可以使用designated initializers将结构体的字段设置为值,如下:

struct MyStruct {
    int x;
    float f;
};

void test() {
    struct MyStruct s = {.x=123, .f=456.789};
}

【讨论】:

  • 不,我的意思是我想初始化成员而不使用任何函数来初始化其成员
  • @lemoncodes C 中没有动态初始化工具。你需要 C++ :(
  • 这就是 C++ 的用途——它允许您在类和结构中拥有函数。在 C 中,您不能在不编写代码初始化结构的情况下将函数与类关联(当然,您可以执行与 C++ 中相同的操作,使用“vtable”,这意味着每个结构类型只需一个初始化)常量函数数组)
  • hmmmm 所以没有办法完全模仿 OOP 中的类而不做任何额外的函数来初始化 C 中结构的成员?我的意思是严格地说 C 而不是 C++
  • @lemoncodes 正确,纯 C 不提供在没有函数的情况下执行初始化代码的方法。
【解决方案2】:
StructName s; // receives no initialization
StructName s = {x,y}; // value initializes all members 

struct Child { StructName s; };
Child c; // receives no initialization
Child c = {x,y}; // value initializes all members

For Example :

struct Child{

int c;
int d;

}

Child childstruct ={10,20};

那么 childstruct.c 将为 10 并且 childstruct.d 将为 20。

http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Flanguage%2Fref%2Fclrc03strin.htm

【讨论】:

  • 我已经知道这部分了,我想做的是初始化结构内的成员。就像 OOP 中的类,但我在 C 而不是 C++ 上实现它
【解决方案3】:

在对内存有些紧张的嵌入式系统进行编程时,我使用的一种方法是使用一些宏来定义结构类型并定义其初始值。定义类似于:

#define CREATE_FOO_STRUCT \
  X(int age, 34) Y \
  X(int height, 65) Y \
  X(char const * favoritecolor,"blue") Y \
  X(int some_things[5],ARR5(1,2,3,4,5))

需要ARR5 宏来允许将该数组的初始化值作为单个参数传递;另一种方法是将最后一行写为X(int some_things[5],{1 COMMA 2 COMMA 3 COMMA 4 COMMA5})。给定一个像上面这样的宏,可以定义XY,所以X返回扩展为第一项,Y扩展为分号,在这种情况下typedef {CREATE_FOO_STRUCT} FOO;将定义结构FOO,然后重新定义XY 以便X 返回第二个项目,Y 一个逗号,在这种情况下const FOO default_FOO = {CREATE_FOO_STRUCT}; 将定义一个默认实例。太糟糕了,我不知道有什么方法可以避免最后一行与其他行不同(如果每一行 但第一行 前面有 @987654335,则最后一行可以匹配其他行@,如果最后一行后面跟着 //this line must be left blank 行。

在我实现上述结构的特定处理器上,以这种方式定义 default_FOO 将消耗零 RAM,并消耗等于 default_FOO 大小的 ROM。使用常规赋值语句加载具有默认值的FOO 的静态实例的函数将为default_FOO 中的每个非零字节消耗四个字节的ROM,并且还需要它有一个静态实例可以用。接受FOO* 并使用默认值加载指向的实例的 C 语言函数将占用大量代码(每个分配都必须单独计算要存储的数据的地址)。

【讨论】:

    【解决方案4】:

    在 C 中初始化结构模板内的结构成员是非法,并且是不允许..因为结构模板不拥有自己的任何内存,并且 struct 的所有成员仅在与 struct 类型的变量关联时才分配内存空间,并且由于现在为它们分配了可以初始化的内存..但在与变量关联之前不能:例如

        struct tag_name
        { 
        int x;
        int y;
        };
    

    上述结构模板不包含内存空间.. 除非有一个变量与它相关联:

        struct tag_name variable1;
    

    现在变量variable1的struct类型将被分配一个足够大的内存来保存两个int值(对于variable1.xvariable1. y) 现在只有您可以将成员 x 和 y 初始化为例如:

        variable1.x=10;
        variable1.y=20;
    

    因此以下内容将是非法的

        struct tag_name
        { 
        int x=10;
        int y=20;
        };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 2020-08-21
      相关资源
      最近更新 更多