开发者

About default C struct values, what about this code?

I'm trying to create structs with default values. I don't know how to accomplish this because every code that I see, is about initialising, and I would it for the natural way like...

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

and looking about, I found this (C++) code:

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

I never saw anything like this for C. Please, help me to understand it; I think that it is very nice!

UPDATE: Wait, I'm asking about C!!!! Why changed my question? If that is not possible in C just say... I don't know C++, I didn't know that was about C++.开发者_如何转开发..


If you want to set a struct object in one go and you have a C99 compiler, try this:

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

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

Otherwise, with a C89 compiler, you have to set each member one by one:

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

Running example @ ideone : http://ideone.com/1QqCB


The original line

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

is a syntax error in C.


As you have probably learned from the other answers, in C you can't declare a structure and initialize it's members at the same time. These are different tasks and must be done separately.

There are a few options for initializing member variables of a struct. I'll show a couple of ways below. Right now, let's assume the following struct is defined in the beginning of the file:

struct stuff {
  int stuff_a;
  int stuff_b;
};

Then on your main() code, imagine that you want to declare a new variable of this type:

struct stuff custom_var;

This is the moment where you must initialize the structure. Seriously, I mean you really really must! Even if you don't want to assign specific values to them, you must at least initialize them to zero. This is mandatory because the OS doesn't guarantee that it will give you a clean memory space to run your application on. Therefore, always initialize your variables to some value (usually 0), including the other default types, such as char, int, float, double, etc...

One way to initialize our struct to zero is through memset():

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

Another is accessing each member individually:

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

A third option, which might confuse beginners is when they see the initialization of struct members being done at the moment of the declaration:

struct stuff custom_var = { 1, 2 };

The code above is equivalent to:

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


... create structs with default values ...

That is impossible in C. A type cannot have default values. Objects of any type cannot have a default value other than 0, though they can be initialized to whatever is wanted.
The definition of a struct is a definition of a type, not of an object.


What you asking is about the same thing as a way to have ints default to, say, 42.

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

Or, adapting to your example

/* 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 */


Update: This answer assumes we 're talking about C++ because the code posted in the answer is not legal C.

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

The line marked with the comment is simply the constructor for instances of struct a (reminder: structs are just like classes, except that the default member visibility is public instead of private).

The part after the : is called an initialization list: it allows you to initialize the members of the struct with values (either constants or passed as constructor parameters). Initialization of members in this list happens before the body of the constructor is entered. It is preferable to initialize members of classes and structs this way, if at all possible.

See also C++: Constructor versus initializer list in struct/class.


in C (pre C99) the following also works:

#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);
}

See codepad


I'm not sure quite sure what your problem is. The standard way of initialising structures in c is like this:

struct a_struct my_struct = {1, 2};

Or the more recent and safer:

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

If there is more than one instance of a structure, or it needs to be re-initialised, it is useful to define a constant structure with default values then assign that.

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;
}


Type initializer is not possible in C.

  • A value must be stored in the memory.
  • A type does not occupy memory, what occupies memory is a variable of that type.

    struct stuff; is a type; it does not occupy memory

    struct stuff aStuff; is a variable of that type; aStuff occupies memory

  • Because a type does not occupy memory, it is not possible to save values into a type.

  • If there is syntactic sugar to support store/initialize values into a type then there must be additional code that is inserted to assign values to every instant variables of that type (e.g: in constructor in C++). This will result in a less efficient C if this feature is available.

  • How often do you need to retain this default values? I think it is unlikely. You can create a function to initialize variable with the default values or just initialize every fields with the values you want. So type initializer is not fundamental thing. C is about simplicity.


Can't initialize values within a structure definition.

I'd suggest:

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;
}

Before the days of Object Oriented Programming (C++), we were taught "Abstract Data Types".

The discipline said 'never access your data structures directly, always create a function for it' But this was only enforced by the programmer, instructor, or senior developer, not the language.

Eventually, the structure definition(s) and corresponding functions end up in their own file & header, linked in later, further encapsulating the design.

But those days are gone and replaced with 'Class' and 'Constructor' OOP terminology.

"It's all the same, only the names have changed" - Bon Jovi.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜