How to Initialize a Struct in C

Jinku Hu Feb 02, 2024
  1. Use Designated Initializers to Initialize a Struct in C
  2. Use Compound Literals to Initialize a Struct in C
  3. Use Explicit Assignments to Initialize a Struct in C
  4. Use Constructors (in C99 and Later) to Initialize a Struct in C
  5. Conclusion
How to Initialize a Struct in C

Structs in C provide a powerful mechanism for grouping variables of diverse data types under a unified name. Properly initializing a struct is crucial for ensuring the correct functioning of your programs.

In this article, we’ll explore various methods to initialize a struct in C, each offering its advantages.

Use Designated Initializers to Initialize a Struct in C

In C programming, structs serve as a pivotal tool for grouping variables of diverse data types under a unified name. When it comes to initializing a struct, one particularly versatile technique is the use of designated initializers.

This method allows for explicit specification of which members of the struct to initialize, offering clarity and flexibility in code organization.

The syntax for designated initializers involves specifying the member name followed by an equal sign and the value to assign. The general form looks like this:

struct MyStruct {
  int member1;
  float member2;
  char member3;
};

struct MyStruct instance = {
    .member1 = value1, .member2 = value2, .member3 = value3};

This syntax allows initializing specific members of the struct while leaving others uninitialized, fostering flexibility in struct initialization.

Let’s dive into an example featuring a Person struct, representing an individual’s first name, last name, age, and a boolean indicating their vitality. Designated initializers will be employed to create an instance of this struct.

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Person {
  char firstname[40];
  char lastname[40];
  int age;
  bool alive;
} Person;

int main(void) {
  Person me = {.firstname = "John\0",
               .lastname = "McCarthy\0",
               .age = 24,
               .alive = true};

  printf("Name: %s\nLast Name: %s\nAge: %d\nAlive: ", me.firstname, me.lastname,
         me.age);
  me.alive ? printf("Yes\n") : printf("No\n");

  exit(EXIT_SUCCESS);
}

Output:

Name: John
Last Name: McCarthy
Age: 24
Alive: Yes

In this code snippet, we include necessary header files (stdbool.h, stdio.h, stdlib.h, string.h) and define a Person struct using typedef. The struct encapsulates members for the first name (firstname), last name (lastname), age, and a boolean indicating whether the person is alive (alive).

In the main function, we create an instance of the Person struct named me. Using designated initializers, we initialize each member of the struct with specific values.

The first name is set to John, the last name to McCarthy, the age to 24, and the alive status to true.

The subsequent printf statement displays the information stored in the me struct. It prints the first name, last name, and age using the %s and %d format specifiers, respectively.

The last part of the output depends on the boolean value of the alive member. If alive is true, Yes is printed; otherwise, No is printed.

Finally, the program exits with EXIT_SUCCESS, indicating successful execution.

Use Compound Literals to Initialize a Struct in C

Another versatile technique to initialize a struct is using compound literals. This method allows for the creation of temporary instances of a struct with specific initial values.

The syntax for compound literals involves enclosing a list of values within parentheses and casting them to the desired struct type. The general form looks like this:

(struct MyStruct) { value1, value2, value3 }

This syntax allows for the creation of an unnamed temporary instance of the struct with the specified initial values.

Let’s delve into a practical example using the Person struct:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct Person {
  char firstname[40];
  char lastname[40];
  int age;
  bool alive;
} Person;

int main(void) {
  Person me;
  me = (Person){
      .firstname = "John\0", .lastname = "McCarthy\0", .age = 24, .alive = 1};

  printf("Name: %s\nLast Name: %s\nAge: %d\nAlive: ", me.firstname, me.lastname,
         me.age);
  me.alive ? printf("Yes\n") : printf("No\n");

  exit(EXIT_SUCCESS);
}

In this example, we have a Person struct representing an individual’s first name, last name, age, and alive status. The main function initializes an instance of this struct named me using a compound literal.

The compound literal (Person){.firstname = "John\0", .lastname = "McCarthy\0", .age = 24, .alive = 1} creates a temporary instance of the Person struct with each member explicitly initialized.

This method combines clarity and conciseness, eliminating the need for a separate declaration and assignment step.

The subsequent printf statement displays the information stored in the me struct, presenting the first name, last name, age, and alive status. The output, in this case, would be:

Name: John
Last Name: McCarthy
Age: 24
Alive: Yes

Using compound literals in this manner enhances the readability of the code, making it clear and expressive. This approach is particularly advantageous when immediate struct initialization is preferred, providing a streamlined and elegant solution for struct initialization in C.

Use Explicit Assignments to Initialize a Struct in C

When initializing struct members in C, an alternative method involves declaring a variable and assigning each member with its corresponding value individually. This approach is characterized by explicit assignments, making it clear and straightforward.

It’s worth noting that when dealing with char arrays, assigning them directly with strings isn’t allowed in C. Instead, explicit copying using functions like memcpy or memmove is necessary (refer to the manual for more details).

Additionally, care should be taken to ensure that the length of the array is not less than the string being stored.

Here’s an illustrative example using a Person struct:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Person {
  char firstname[40];
  char lastname[40];
  int age;
  bool alive;
} Person;

int main(void) {
  Person me2;

  memcpy(&me2.firstname, "Jane\0", 40);
  memcpy(&me2.lastname, "Delaney\0", 40);
  me2.age = 27;
  me2.alive = true;

  printf("Name: %s\nLast Name: %s\nAge: %d\nAlive: ", me2.firstname,
         me2.lastname, me2.age);
  me2.alive ? printf("Yes\n") : printf("No\n");

  exit(EXIT_SUCCESS);
}

As we can see in this example, each member of the me2 instance is assigned a value individually. Here, the use of memcpy ensures the proper copying of string values into char arrays, respecting the necessary length constraints.

The subsequent printf statement remains unchanged, displaying the information stored in the me2 struct. The output, as before, will be:

Name: Jane
Last Name: Delaney
Age: 27
Alive: Yes

While this approach is valid, it often involves more lines of code and can be less concise compared to using compound literals, as demonstrated in the previous section.

Compound literals provide a more streamlined and expressive way to initialize structs in C, especially when dealing with immediate initialization or temporary instances.

Use Constructors (in C99 and Later) to Initialize a Struct in C

The concept of constructors, while not native, like in some other languages, can be emulated to achieve struct initialization.

C99 and later versions allow for a more expressive and organized approach by enabling the use of designated initializers within functions. This technique can be likened to a constructor, allowing for structured and customizable initialization of structs.

The syntax for creating a constructor-like function involves defining a function that returns an instance of the struct with designated initializers.

Here’s an example using a Person struct:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Person {
  char firstname[40];
  char lastname[40];
  int age;
  bool alive;
} Person;

Person createPerson(const char* first, const char* last, int age, bool alive) {
  Person newPerson;
  strncpy(newPerson.firstname, first, sizeof(newPerson.firstname) - 1);
  strncpy(newPerson.lastname, last, sizeof(newPerson.lastname) - 1);
  newPerson.age = age;
  newPerson.alive = alive;

  return newPerson;
}

int main(void) {
  Person me = createPerson("Jane", "Delaney", 27, true);

  printf("Name: %s %s\nAge: %d\nAlive: %s\n", me.firstname, me.lastname, me.age,
         me.alive ? "Yes" : "No");

  exit(EXIT_SUCCESS);
}

In this example, we define a Person struct with members for the first name, last name, age, and alive status. Here, the createPerson function serves as a constructor-like function, initializing and configuring a Person struct with specific values.

The function uses strncpy to copy the first and last names into the struct’s firstname and lastname members, respectively. It also ensures null-termination of the strings to prevent potential buffer overflows.

The age and alive members are then set according to the provided arguments.

In the main function, the createPerson function is used to initialize a Person struct named me. The subsequent printf statement displays the information stored in the me struct, showcasing the first name, last name, age, and alive status.

Name: Jane Delaney
Age: 27
Alive: Yes

This constructor-like approach offers a structured and modular way to initialize structs in C, providing a clear and organized solution for customizable struct initialization.

Conclusion

Initializing structs in C involves a range of techniques, each catering to different preferences and scenarios.

Designated initializers offer clarity and flexibility, whereas compound literals provide immediate initialization. Explicit assignments ensure straightforward initialization and constructors (in C99 and later) allow for a structured approach.

Choose the method that aligns with your coding style and the specific requirements of your program. Whether you prioritize clarity, conciseness, or modularity, understanding these initialization techniques will empower you to write more efficient and maintainable C code.

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C Struct