关于默认的C struct值,这段代码怎么样?

时间:2011-03-28 22:43:44

标签: c struct

我正在尝试使用默认值创建结构。我不知道如何实现这个目标,因为我看到的每一个代码都是关于初始化的,我会以自然的方式来做... ...

struct stuff {
  int stuff_a = 1;
  int stuff_b = 2...
  ...and so on...
};

然后看,我找到了这个(C ++)代码:

struct a{   a() : i(0), j(0) {};  INT i;   INT j;}

我从未见过这样的事情。请帮助我理解;我认为这很好!

更新:等等,我问的是C !!!!为什么改变我的问题?如果在C中不可能这样说...我不懂C ++,我不知道那是关于C ++的......

8 个答案:

答案 0 :(得分:15)

如果你想一次性设置结构对象你有一个C99编译器,试试这个:

struct stuff {
    int stuff_a;
    int stuff_b;
    // and so on...
};

struct stuff foo;
/* ... code ... */
foo = (struct stuff){.stuff_b = 42, .stuff_a = -1000};

否则,使用C89编译器,您必须逐个设置每个成员:

foo.stuff_b = 42;
foo.stuff_a = -1000;

运行示例@ ideone:http://ideone.com/1QqCB


原始行

struct a{   a() : i(0), j(0) {}   INT i;   INT j;}

是C中的语法错误。

答案 1 :(得分:10)

正如您可能从其他答案中学到的,中的您无法声明结构并同时初始化其成员。这些是不同的任务,必须单独完成。

初始化结构的成员变量有几个选项。我将在下面展示几种方式。现在,让我们假设文件开头的已定义以下结构:

struct stuff {
  int stuff_a;
  int stuff_b;
};

然后在您的main()代码中,假设您想声明此类型的新变量:

struct stuff custom_var;

这是必须初始化结构的时刻。说真的,我的意思是你真的非常必须!即使您不想为它们分配特定值,也必须至少将它们初始化为零。这是强制性的,因为操作系统不保证它会为您提供一个干净的内存空间来运行您的应用程序。因此,始终将变量初始化为某个值(通常为0),包括其他默认类型,如char,int,float,double等......

将结构初始化为零的一种方法是memset()

memset(&custom_var, 0, sizeof(struct stuff));

另一个是分别访问每个成员:

custom_var.stuff_a = 0;
custom_var.stuff_b = 0;

第三个选项可能会让初学者感到困惑的是当他们看到结构成员的初始化在声明时完成:

struct stuff custom_var = { 1, 2 };

上面的代码相当于:

struct stuff custom_var;
custom_var.stuff_a = 1;
custom_var.stuff_b = 2;

答案 2 :(得分:7)

  

...使用默认值创建结构...

在C.中这是不可能的。 类型不具有默认值。任何类型的对象都不能具有0以外的默认值,但它们可以初始化到任何需要的内容。
struct的定义是类型的定义,而不是对象的定义。


你提出的问题与将int默认为42的方式相同。

/* WRONG CODE -- THIS DOES NOT WORK */
typedef int int42 = 42;
int42 a;
printf("%d\n", a); /* print 42 */

或者,适应你的例子

/* WRONG CODE -- THIS DOES NOT WORK */
struct stuff {
    int42 stuff_a;
    int65536 stuff_b;
}
struct stuff a;
printf("%d\n", a.stuff_b); /* print 65536 */

答案 3 :(得分:6)

更新:这个答案假设我们正在谈论C ++,因为答案中发布的代码不是合法的C.

 struct a {
     a() : i(0), j(0) {}   // constructor with initialization list
     int i;
     int j;
 }

标记注释的行只是struct a实例的构造函数(提醒:结构就像类一样,但默认成员可见性为public而不是private

:之后的部分称为初始化列表:它允许您使用值(常量或作为构造函数参数传递)初始化struct的成员。此列表中成员的初始化发生在输入构造函数的主体之前。 <{3}}以这种方式初始化类和结构的成员,如果可能的话。

另见preferable

答案 4 :(得分:3)

在C(前C99)中,以下也有效:

#include <stdio.h>
typedef struct
{
    int a;  
    int b;
    int c;
 } HELLO;

int main()
{
HELLO a = {1,2,3};

printf("here: %d %d %d\n",a.a,a.b,a.c);
exit(1);
}

请参阅codepad

答案 5 :(得分:3)

我不确定你的问题是什么。在c中初始化结构的标准方法是这样的:

struct a_struct my_struct = {1, 2};

或者更近些更安全:

struct a_struct my_struct = {.i1 = 1, .i2 = 2};

如果有一个结构的实例,或者需要重新初始化,那么定义一个带有默认值的常量结构然后分配它是很有用的。

typedef struct a_struct {
   int i1;
   int i2;
} sa;

static const sa default_sa = {.i1 = 1, .i2 = 2};

static sa sa1 = default_sa;
static sa sa2 = default_sa;

// obviously you can do it dynamically as well
void use_temp_sa(void)
{
     sa temp_sa = default_sa;
     temp_sa.i2 = 3;
     do_something_with(&temp_sa);
}

// And re-initialise
void reset_sa(sa *my_sa)
{
    *my_sa = default_sa;
}

答案 6 :(得分:3)

C中无法使用类型初始值设定项。

  • 必须将值存储在内存中。
  • 类型不占用内存,占用内存的是该类型的变量。

    struct stuff;是一种类型;它没有占用记忆

    struct stuff aStuff;是该类型的变量; aStuff占用记忆

  • 因为类型不占用内存,it is not possible to save values into a type

  • 如果存在支持将值/初始值存储为类型的语法糖,则必须插入additional code以将值分配给该类型的每个即时变量(例如:{{1} })。如果此功能可用,这将导致效率降低。

  • 您需要多久保留一次此默认值?我认为这不太可能。您可以创建一个函数来使用默认值初始化变量,或者只使用所需的值初始化每个字段。所以类型初始化器不是基本的东西。 constructor in C++

答案 7 :(得分:3)

无法初始化结构定义中的值。

我建议:

typedef struct {
   int stuff_a;
   int stuff_b;
} stuff ;

int stuffInit(int a, int b, stuff *this){
   this->stuff_a = a;
   this->stuff_b = b;
   return 0; /*or an error code, or sometimes '*this', per taste.*/
}


int main(void){
   stuff myStuff;
   stuffInit(1, 2, &myStuff);

   /* dynamic is more commonly seen */
   stuff *dynamicStuff;
   dynamicStuff = malloc(sizeof(stuff));  /* 'new' stuff */
   stuffInit(0, 0, dynamicStuff);
   free(dynamicStuff);                    /* 'delete' stuff */

   return 0;
}

在面向对象编程(C ++)之前,我们学习了“抽象数据类型”。

该学科说'永远不会直接访问你的数据结构,总是为它创建一个函数'但这只是由程序员,讲师或高级开发人员强制执行,而不是语言。

最终,结构定义和相应的功能最终会出现在他们自己的文件中。标题,稍后链接,进一步封装设计。

但那些日子已经过去了,取而代之的是“Class”和“Constructor”OOP术语。

“一切都一样,只有名字发生了变化” - Bon Jovi。