在一个结构体中,成员能否被初始化为一个值?

4

我想知道在结构体内声明和定义的变量能否被初始化为特定值,我打算使用函数指针来模拟面向对象编程中的类。

示例代码:

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

void main()
{
    getch();
}

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

1
请查看https://dev59.com/NXVC5IYBdhLWcg3wpS7g - cjm
1
我不理解你链接中的这一部分:“直接的答案是因为结构定义声明了一个类型,而不是可以初始化的变量。你的例子是:struct s { int i=10; }; 这并没有声明任何变量 - 它定义了一个类型。要声明一个变量,你需要在}和;之间添加一个名称,然后在之后初始化它:struct s { int i; } t = { 10 };” - lemoncodes
要声明一个变量,你需要在 } 和 ; 之间添加一个名称,然后在之后初始化它:struct s { int i; } t = { 10 }; - lemoncodes
请查看https://dev59.com/kFXTa4cB1Zd3GeqP3qr6。 - pmg
请查看我的编辑过的帖子,添加了一些示例代码。 - lemoncodes
(另外,如果想在C语言中模拟“面向对象”的对象,请参考GObject及其类似的库。) - user166390
4个回答

9

从C99开始,您可以使用指定初始化器将结构体的字段设置为特定的值,如下所示:

struct MyStruct {
    int x;
    float f;
};

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

不,我的意思是我想初始化成员,而不需要编写任何函数来初始化它的成员。 - lemoncodes
@lemoncodes 在 C 语言中没有动态初始化的功能。你需要使用 C++ 来实现它 :( - Sergey Kalinichenko
这就是C ++的作用 - 它允许您在类和结构中拥有函数。在C中,您不能将函数与类关联起来,除非编写代码以初始化结构(当然,您可以像在C ++中一样执行相同的操作,使用“ vtable”,这意味着每种struct类型仅需一次初始化到常量数组中的函数)。 - Mats Petersson
嗯,所以在C语言中没有办法完全模拟面向对象编程中的类,而不需要创建任何额外的函数来初始化结构体的成员吗?我的意思是严格地说只考虑C语言,而不是C++。 - lemoncodes
1
@lemoncodes 正确,纯C没有一种方法可以在没有函数的情况下执行初始化代码。 - Sergey Kalinichenko

0

我已经知道这个部分,我想做的是初始化结构体内的成员变量。就像面向对象编程中的类一样,但我是在C而不是C++中实现它。 - lemoncodes

0

当我在编写内存有限的嵌入式系统时,我使用过一种方法,即使用一些宏来定义结构类型并定义其初始值。定义大致如下:

#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};将定义默认实例。很遗憾我不知道如何避免需要让最后一行与其他行不同(如果每行除了第一行之外都在X之前,并且如果最后一行后面跟着一个//此行必须留空行,则最后一行可以与其他行匹配)。

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

0
在C语言中,在结构模板内部初始化结构成员是非法的,并且不被允许。因为结构模板本身不持有任何内存,只有当结构体类型变量与其相关联时,结构体的所有成员才会分配内存空间。由于现在它们已经分配了内存,所以可以进行初始化,但必须在与变量相关联之后才能进行初始化,例如:
    struct tag_name
    { 
    int x;
    int y;
    };

上述结构模板不占用内存空间.. 除非将变量与其关联,如下:

    struct tag_name variable1;

现在变量variable1的结构类型将被分配足够大的内存来容纳两个int值(用于variable1.xvariable1.y),现在只有您可以初始化成员x和y,例如:

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

因此,以下内容将是非法的。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接