Skip to content
  • Structures · C

Structures

LearnViaNotes @learnvianotes· 4 min read

A struct groups related values of different types into one object — C’s building block for records, and for every data structure.

Define, initialise, access

C
#include <stdio.h>
#include <string.h>

struct Student {
    int id;
    char name[20];
    double gpa;
};

int main(void) {
    struct Student a = {1, "Asha", 8.9};                        /* positional */
    struct Student b = {.name = "Ravi", .gpa = 7.5, .id = 2};   /* designated (C99) */
    struct Student c = {0};                                     /* all zero */

    c.id = 3;
    strcpy(c.name, "Meera");
    c.gpa = 9.2;

    struct Student *p = &c;
    p->gpa += 0.1;                     /* p->gpa is (*p).gpa */

    printf("%d %s %.1f\n", a.id, a.name, a.gpa);
    printf("%d %s %.1f\n", b.id, b.name, b.gpa);
    printf("%d %s %.1f\n", p->id, (*p).name, p->gpa);
    return 0;
}
Output
1 Asha 8.9
2 Ravi 7.5
3 Meera 9.3
OperatorUse withExample
.a struct objects.gpa
->a pointer to a structp->gpa ≡ (*p).gpa

Copying, passing and returning

C
#include <stdio.h>

typedef struct { double x, y; } Point;

Point midpoint(Point a, Point b) {          /* by value: copies in, copy out */
    return (Point){(a.x + b.x) / 2, (a.y + b.y) / 2};    /* compound literal */
}

void translate(Point *p, double dx, double dy) {         /* by pointer: modifies caller */
    p->x += dx;
    p->y += dy;
}

int main(void) {
    Point a = {0, 0}, b = {4, 2};
    Point m = midpoint(a, b);
    Point copy = m;                 /* struct assignment copies every member */
    translate(&m, 1, 1);
    printf("m=(%.1f,%.1f) copy=(%.1f,%.1f)\n", m.x, m.y, copy.x, copy.y);
    return 0;
}
Output
m=(3.0,2.0) copy=(2.0,1.0)

Nested structs and arrays of structs

C
#include <stdio.h>

struct Date { int d, m, y; };
struct Employee {
    char name[16];
    struct Date joined;           /* nested */
    double salary;
};

int main(void) {
    struct Employee staff[] = {
        {"Anil", {1, 4, 2020}, 50000},
        {"Bina", {15, 9, 2018}, 72000},
        {"Chen", {3, 1, 2022}, 61000},
    };
    int n = sizeof staff / sizeof staff[0];
    double total = 0;
    for (int i = 0; i < n; i++) {
        total += staff[i].salary;
        printf("%-5s joined %02d/%02d/%d\n", staff[i].name,
               staff[i].joined.d, staff[i].joined.m, staff[i].joined.y);
    }
    printf("average salary %.0f\n", total / n);
    return 0;
}
Output
Anil  joined 01/04/2020
Bina  joined 15/09/2018
Chen  joined 03/01/2022
average salary 61000

Self-referential structs

C
#include <stdio.h>

struct Node {
    int value;
    struct Node *next;        /* a pointer to its own type is fine; a Node member is not */
};

int main(void) {
    struct Node c = {3, NULL}, b = {2, &c}, a = {1, &b};
    for (struct Node *n = &a; n != NULL; n = n->next) printf("%d -> ", n->value);
    printf("NULL\n");
    return 0;
}
Output
1 -> 2 -> 3 -> NULL

Flexible array member (C99)

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

typedef struct {
    size_t len;
    char data[];               /* flexible array member: must be last */
} Buffer;

int main(void) {
    const char *text = "variable length";
    size_t n = strlen(text) + 1;
    Buffer *b = malloc(sizeof *b + n);   /* header + payload in ONE allocation */
    if (!b) return 1;
    b->len = n - 1;
    memcpy(b->data, text, n);
    printf("%zu: %s (sizeof Buffer = %zu)\n", b->len, b->data, sizeof(Buffer));
    free(b);
    return 0;
}
Output
15: variable length (sizeof Buffer = 8)

Opaque types: encapsulation in C

Declaring struct Stack; in a header without its body (an incomplete type) lets users hold struct Stack * but not touch the fields — only functions in stack.c can. This is how FILE works.

C — header of an opaque type (compile-checked)
/* stack.h */
typedef struct Stack Stack;           /* opaque: fields hidden */
Stack *stack_new(void);
void   stack_push(Stack *s, int v);
int    stack_pop(Stack *s);
void   stack_free(Stack *s);

What is the difference between . and -> ?

Can you compare two structs with ==?

Why can't a struct contain a member of its own type?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report