Mastering C Structs: Definitions, Alignment, and Practical Usage
This guide explains C structs—from basic definitions and declaration styles to memory alignment, byte sizing, bit‑field handling, nested structures, and using structs as function parameters—providing clear code examples and practical tips for efficient embedded and systems programming.
What Is a Struct?
A struct groups heterogeneous data members into a single composite type.
Declaration vs Definition
A declaration describes the layout without allocating memory:
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};Variables are created after the type is declared.
Three Common Ways to Define a Struct in C
Separate declaration and definition :
#include <stdio.h>
struct student {
int age;
float score;
char sex;
};
int main(void) {
struct student a = {20, 79.0f, 'f'};
printf("Age:%d Score:%.2f Sex:%c
", a.age, a.score, a.sex);
return 0;
}Combined declaration‑definition (single use):
#include <stdio.h>
struct student { int age; float score; char sex; } a = {21, 80, 'n'};
int main(void) {
printf("Age:%d Score:%.2f Sex:%c
", a.age, a.score, a.sex);
return 0;
}Anonymous struct variable (no tag name) :
#include <stdio.h>
struct { int age; float score; char sex; } t = {21, 79, 'f'};
int main(void) {
printf("Age:%d Score:%f Sex:%c
", t.age, t.score, t.sex);
return 0;
}Defining Struct Variables
After the type is declared, create variables:
struct book library; // allocates one instanceAccess members with the dot operator:
printf("%s
%s
%f", library.title, library.author, library.value);Initialization
Struct initialization mirrors array initialization using braces and commas. Each initializer must match the corresponding member’s type.
struct book s1 = {
"yuwen", // title
"guojiajiaoyun", // author
22.5 // value
};For objects with static storage, all initializer values must be constant expressions.
Memory Alignment and Size
Compilers align each member to its natural boundary (often 4 bytes on 32‑bit CPUs). Padding may be added after members and at the end of the struct. Alignment can be changed with #pragma pack(n) where n is 1, 2, 4, 8, or 16.
Alignment Rules
Each member is placed at the smallest offset that satisfies both the #pragma pack value and the member’s own size.
After all members are placed, the whole struct is padded to satisfy the same rule using the largest member size.
If the #pragma pack value is greater than or equal to all member sizes, it has no effect.
Example (8‑byte struct due to a 4‑byte int member):
typedef struct {
char addr; // 1 byte
char name; // 1 byte
int id; // 4 bytes, forces 4‑byte alignment
} PERSON;Bit‑Field Structs
Bit fields pack sub‑byte data within an underlying integer type.
typedef struct {
uint32_t SYMBOL_TYPE :5;
uint32_t reserved_1 :4;
uint32_t SYMBOL_NUMBER :7;
uint32_t SYMBOL_ACTIVE :1;
uint32_t SYMBOL_INDEX :8;
uint32_t reserved_2 :8;
} SYMBOL_STRUCT;The compiler allocates space in units of the underlying type (here 4 bytes). When a bit‑field does not fit in the current unit, a new unit is started.
Nested Structs
Structs can contain other structs, enabling hierarchical data models.
typedef struct {
char addr;
char name;
int id;
} PERSON;
typedef struct {
char age;
PERSON ps1; // nested struct
} STUDENT;Access nested members with chained dot operators, e.g., student.ps1.id .
Structs as Function Parameters
Encapsulating related arguments in a struct reduces repetitive code and improves maintainability. Pass by pointer to avoid copying the whole struct.
struct video_info {
char *name;
long address;
int size;
int alg;
time_t time;
};
int get_video(struct video_info *v);
int handle_video(struct video_info *v);
int send_video(struct video_info *v);
int main(void) {
struct video_info v = {0};
get_video(&v);
handle_video(&v);
send_video(&v);
return 0;
}Passing a pointer avoids the overhead of copying; passing by value is also possible but incurs extra cost.
Struct Size, Padding, and Ordering
The size of a struct is not simply the sum of its members because of alignment padding. Reordering members can reduce wasted space.
typedef struct {
char addr; // 1 byte
char name; // 1 byte
int id; // 4 bytes (adds 2 bytes padding after the two chars)
} PERSON; // sizeof(PERSON) == 8 on a 32‑bit systemPlacing the largest member first often yields a smaller overall size:
typedef struct {
int id; // 4 bytes
char addr; // 1 byte
char name; // 1 byte
} PERSON; // sizeof(PERSON) == 6 (plus possible trailing padding to satisfy overall alignment)Typedef for Convenience
Use typedef to create an alias for a struct type, making declarations shorter.
typedef struct {
int date;
/* … */
} STUDENT;
STUDENT s1, s2; // no need to write "struct" each timeBit‑Field Layout Details (Embedded Example)
When the underlying type is uint32_t , the compiler allocates 4‑byte units. Changing the base type to uint8_t reduces the allocation unit to 1 byte.
typedef struct {
uint8_t SYMBOL_TYPE :5;
uint8_t reserved_1 :4;
uint8_t SYMBOL_NUMBER :7;
uint8_t SYMBOL_ACTIVE :1;
uint8_t SYMBOL_INDEX :8;
uint8_t reserved_2 :8;
} SYMBOL_STRUCT;In this configuration the entire bit‑field occupies exactly 4 bytes (32 bits) with no extra padding.
Key Takeaways
Structs provide a way to group heterogeneous data into a single type.
Memory alignment and padding affect the actual size; #pragma pack can control alignment.
Bit fields pack data tightly within an underlying integer type, but alignment rules still apply.
Nested structs enable complex data hierarchies.
Encapsulating related parameters in a struct reduces code duplication and improves maintainability.
Member ordering and appropriate use of typedef can minimize padding and struct size.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
