Last 30 Days
No notifications
A struct lets you bundle several variables of different types into ONE named unit. It's how C programs model "things" — a Student, a Point, a Date, a Book.
struct Student {
int id;
char name[50];
float cgpa;
};struct Student s = {1, "Asha", 8.9f};
printf("%s scored %.2f\n", s.name, s.cgpa);
| You have | Use |
A struct value (s) | s.field (dot) |
A struct pointer (p) | p->field (arrow) |
struct Student *p = &s;
p->cgpa = 9.1f; /* same as (*p).cgpa */typedef struct {
int x, y;
} Point;Point a = {3, 4}; /* no need to write "struct Point" */
They are the foundation of every data structure in C — linked lists, trees, graphs, hash tables — all built from structs that contain pointers to other structs.
Structs are how C programs talk about real-world entities. Without them you'd be juggling parallel arrays — int ids[100], char names[100][50], float cgpas[100] — which is a nightmare to keep in sync. With structs you have ONE Student[100] and every field travels together.
struct Point {
int x;
int y;
};struct Point.struct Point p1; /* uninitialised */
struct Point p2 = {3, 4}; /* x=3, y=4 */
struct Point p3 = {.y = 7}; /* designated init: x=0, y=7 (C99) */Writing struct Point everywhere is annoying. typedef gives the type a one-word name:
typedef struct Point Point; /* now "Point" means "struct Point" */
Point p = {1, 2};The common one-shot form:
typedef struct {
int x, y;
} Point;This declares an anonymous struct and aliases it as Point. After that, you just write Point. Almost all real C code uses this style.
Point p = {3, 4};
p.x = 10; /* dot — for a value */Point *q = &p;
q->y = 20; /* arrow — for a pointer */
(*q).y = 20; /* same thing, ugly */
The arrow -> is just sugar for "dereference then dot". Use it whenever you have a pointer.
Two choices: by value (copy) or by pointer (reference).
/* By value — function gets its own copy */
void print_point(Point p) {
printf("(%d, %d)\n", p.x, p.y);
}/* By pointer — function can modify the original */
void translate(Point *p, int dx, int dy) {
p->x += dx;
p->y += dy;
}
For anything bigger than a few ints, pass by pointer to avoid copying. Add const if you only read:
void print_student(const Student *s); /* fast + safe */Yes, you can return a struct by value:
Point make_point(int x, int y) {
Point p = {x, y};
return p;
}Point origin = make_point(0, 0);
Modern compilers optimise this (return-value optimisation), so don't fear it for small structs.
typedef struct {
int day, month, year;
} Date;typedef struct {
char title[100];
Date published;
float price;
} Book;
Book b = {"K&R C", {1, 2, 1978}, 499.0f};
printf("%d/%d\n", b.published.day, b.published.month);
Student class[3] = {
{1, "Asha", 8.9f},
{2, "Ravi", 7.5f},
{3, "Mira", 9.2f},
};for (int i = 0; i < 3; i++)
printf("%s — %.1f\n", class[i].name, class[i].cgpa);
A struct CAN contain a pointer to its own type — this is how linked structures work:
typedef struct Node {
int value;
struct Node *next; /* must say "struct Node" — typedef name not yet visible */
} Node;A node knows the next node. Chain them up and you've got a linked list. Same trick gives you trees (two child pointers), graphs (an array of pointers), etc.
The compiler may insert invisible "padding" bytes between fields so each one sits on a CPU-friendly address. Means sizeof(struct) can be bigger than the sum of its fields.
struct S {
char c; /* 1 byte */
int i; /* 4 bytes — usually preceded by 3 bytes of padding */
};
/* sizeof(struct S) is often 8, not 5 */You normally don't care. If you do (e.g., writing structs to disk or over a network), put the largest fields first and read about #pragma pack.
| Action | Syntax |
| Define | struct T { ... }; or typedef struct { ... } T; |
| Declare | T x; |
| Init | T x = {1, 2}; |
| Designated init | T x = {.field = val}; |
| Field via value | x.field |
| Field via pointer | p->field |
| Size | sizeof(T) (may include padding) |
| Heap allocate | T *p = malloc(sizeof *p); |
Master structs and you can model anything — and you're one step away from linked lists, trees, and the data structures that make C truly powerful.