How do you declare and initialize structs in C, including C99 designated initializers?
Structs in C group related variables under one name. There are several ways to declare and initialize them:
Declaration:
struct Point { int x; int y; };
Initialization methods:
- Positional initialization:
struct Point p = {10, 20};
Fields are assigned in declaration order.
- C99 designated initializers:
struct Point p = {.x = 10, .y = 20};
Fields are named explicitly -- order does not matter, unspecified fields are zero-initialized.
- Partial initialization:
struct Point p = {10}; /* x=10, y=0 */
Unspecified fields are zero-initialized.
- Zero initialization:
struct Point p = {0}; /* all fields zero */
- Compound literal (C99):
struct Point p = (struct Point){.x = 5, .y = 10};
Designated initializers are a C99 feature and are especially useful for:
- Structs with many fields (only initialize what you need)
- Self-documenting code (field names visible at initialization)
- Forward-compatible code (adding new fields does not break existing initializers)
Positional: struct S s = {val1, val2, val3};
Fields assigned in order; unspecified = 0
Designated (C99): struct S s = {.field2 = val2, .field1 = val1};
Order doesn't matter; unspecified = 0
Zero init: struct S s = {0};
All fields zero-initialized
Compound literal: func((struct S){.x = 1, .y = 2});
#include <stdio.h>
struct Point {
int x;
int y;
};
struct Config {
int width;
int height;
int fullscreen;
int vsync;
int fps_limit;
};
void print_point(struct Point p) {
printf("(%d, %d)\n", p.x, p.y);
}
int main(void) {
/* Positional initialization */
struct Point p1 = {10, 20};
print_point(p1); /* (10, 20) */
/* C99 designated initializers */
struct Point p2 = {.y = 50, .x = 30}; /* order doesn't matter */
print_point(p2); /* (30, 50) */
/* Partial initialization: unspecified fields = 0 */
struct Point p3 = {.x = 7};
print_point(p3); /* (7, 0) */
/* Zero initialization */
struct Point p4 = {0};
print_point(p4); /* (0, 0) */
/* Designated initializers shine with large structs */
struct Config cfg = {
.width = 1920,
.height = 1080,
.fullscreen = 1,
/* vsync and fps_limit default to 0 */
};
printf("Config: %dx%d fullscreen=%d vsync=%d\n",
cfg.width, cfg.height, cfg.fullscreen, cfg.vsync);
/* Compound literal (C99) -- useful for passing to functions */
print_point((struct Point){.x = 100, .y = 200}); /* (100, 200) */
return 0;
}
- •Positional init assigns fields in declaration order
- •C99 designated initializers use .field = value syntax -- order does not matter
- •Unspecified fields are always zero-initialized in both styles
- •{0} zero-initializes the entire struct
- •Compound literals create temporary struct values inline
- •Designated initializers are C99 -- not available in strict C89 mode
- •In C (unlike C++), designated initializer order can differ from declaration order
- •Positional init breaks silently if fields are reordered in the struct definition
- •struct S s; without = {0} leaves fields uninitialized (garbage) -- unlike global structs which are zero-initialized