dev dev - 2 months ago 6
C Question

How do I create an Array of Objects in C?

I'm new to C, coming from a language like javascript the amount of types, keywords etc. in the language are painfully confusing.

In javascript I can create an array of objects like so.

arrayOfObjectsInsideJavascript = [
{ s:"ejf09j290fj390j2f09", f=0 },
{ s:"dj320992209920209dj", f=0 }
]


From what I've read it seems that I'll need to be using
typedef
and or
struct
s.

I've tried:

typedef struct[] = {
{ s:"ejf09j290fj390j2f09", f=0 },
{ s:"dj320992209920209dj", f=0 }
}

struct[] = {
{ s:"ejf09j290fj390j2f09", f=0 },
{ s:"dj320992209920209dj", f=0 }
}

typedef struct {
char[] s = "ejf09j290fj390j2f09";
int f = 0;
} objectLikeClassThingy;


What's the best way to create the object I need?

Answer

Where JavaScript has dynamic "properties", C has static "tags". A struct type is defined as a sequence of tags, which each have a type.

For the type inside your example array

arrayOfObjectsInsideJavascript = [
    { s:"ejf09j290fj390j2f09", f=0 },
    { s:"dj320992209920209dj", f=0 }
]

your last solution started off almost correctly:

struct element {
    char s[256];
    int f;
};

You have two options for the type of s:

  • If you want to store the string inside the object, you use some array type, such as char s[256]. 256 is the length of the array, so when you use zero-terminated strings, the maximum allowed string length is 255 (which is 256, minus one for the '\0' character).
  • If you want to store the string outside the object, you use some pointer type. Since you want to use string literals, you should declare the tag as const char *s. Changing a string literal causes undefined behaviour, so it's best to prevent yourself from doing so.

For this answer, I'll use the first option in the examples.


If you want to define one struct, you could now write something like

struct element {
    char s[256];
    int f;
} one_object = {
    .s = "ejf09j290fj390j2f09",
    .f = 0,
};

or

struct element {
    char s[256];
    int f;
};

/* ... later, in a scope where `struct element` is visible ... */

struct element one_object = {
    .s = "ejf09j290fj390j2f09",
    .f = 0,
};

or, with a typedef,

typedef struct {
    char s[256];
    int f;
} your_element_type;

/* ... later, in a scope where `your_element_type` is visible ... */

your_element_type one_object = {
    .s = "ejf09j290fj390j2f09",
    .f = 0,
};

Note that this doesn't necessarily work with older compilers that don't support the C99 standard. In the older days, you'd have to initialise fields in order:

your_element_type one_object = { "ejf09j290fj390j2f09", 0 };

Also note that, if you're never going to refer to the type name struct element again, you don't have to name it:

struct {
    char s[256];
    int f;
} one_object = {
    .s = "ejf09j290fj390j2f09",
    .f = 0,
};

Arrays are initialised similarly (you've actually already initialised an array, namely s, with a string):

struct element {
    char s[256];
    int f;
} so_many_objects[] = {
    { .s = "ejf09j290fj390j2f09", .f = 0 },
    { .s = "dj320992209920209dj", .f = 0 },
};

or

struct element {
    char s[256];
    int f;
};

/* ... later, in a scope where `struct element` is visible ... */

struct element so_many_objects[] = {
    { .s = "ejf09j290fj390j2f09", .f = 0 },
    { .s = "dj320992209920209dj", .f = 0 },
};

or, with a typedef again,

typedef struct {
    char s[256];
    int f;
} your_element_type;

/* ... later, in a scope where `your_element_type` is visible ... */

your_element_type so_many_objects[] = {
    { .s = "ejf09j290fj390j2f09", .f = 0 },
    { .s = "dj320992209920209dj", .f = 0 },
};

By the way, note that we are using an incomplete type for so_many_objects; this is only possible because the compiler can see how big the array should be. In these examples, the compiler would treat your code as if you'd have written struct element so_many_objects[2]. If you think you'll have to extend the array with more objects, you'd better specify how many elements the array has (at maximum), or learn about dynamic allocation.

Comments