Nearby lessons

100 of 124

C - Structure Declaration

How to declare a structure in C — the struct keyword and tag, the member list, the mandatory semicolon, typedef for a shorter name, and where in your program the declaration belongs.

The Basic Syntax

Four parts: the struct keyword, a tag, a brace-enclosed member list, and a semicolon:

Example01
CCode Cell
1#include <stdio.h>
2 
3struct Student { /* struct keyword + tag + opening brace */
4 char name[30]; /* member */
5 int roll; /* member */
6 float marks; /* member */
7}; /* closing brace + SEMICOLON */
8 
9int main()
10{
11 struct Student s = {"Rahul", 101, 85.5f};
12 
13 printf("%s / %d / %.1f\n", s.name, s.roll, s.marks);
14 return 0;
15}
Output
Rahul / 101 / 85.5

The Semicolon Is Not Optional

Leaving off the semicolon after } produces a baffling error. The compiler assumes the next thing is a variable declaration of this new type, so int main() becomes "a struct Student named main" — and the error message points at main, not at the missing punctuation. If a structure definition gives you nonsense errors on the line after it, check the semicolon first.
Example02
CCode Cell
1/* WRONG - no semicolon
2struct Point {
3 int x, y;
4} <- missing ;
5 
6int main() { ... } <- error reported HERE, not above
7*/
8 
9/* RIGHT */
10struct Point {
11 int x, y;
12};
13 
14int main() { return 0; }
Output
error: two or more data types in declaration specifiers

Declaring Members

Members follow the same rules as ordinary variables — and you may combine same-typed ones on one line:

Example03
CCode Cell
1#include <stdio.h>
2 
3struct Mixed {
4 int a, b, c; /* three ints on one line */
5 float x;
6 char name[20]; /* an array member */
7 char grade;
8 int *ptr; /* a pointer member */
9};
10 
11int main()
12{
13 struct Mixed m;
14 int value = 99;
15 
16 m.a = 1; m.b = 2; m.c = 3;
17 m.x = 4.5f;
18 m.grade = 'A';
19 m.ptr = &value;
20 
21 printf("%d %d %d %.1f %c %d\n",
22 m.a, m.b, m.c, m.x, m.grade, *m.ptr);
23 return 0;
24}
Output
1 2 3 4.5 A 99

Declaring Variables With the Definition

You can create variables in the same statement as the definition, right after the closing brace:

Example04
CCode Cell
1#include <stdio.h>
2 
3struct Point {
4 int x, y;
5} origin = {0, 0}, corner = {100, 100}; /* two variables here */
6 
7int main()
8{
9 struct Point middle = {50, 50}; /* and more later */
10 
11 printf("origin (%d,%d)\n", origin.x, origin.y);
12 printf("middle (%d,%d)\n", middle.x, middle.y);
13 printf("corner (%d,%d)\n", corner.x, corner.y);
14 return 0;
15}
Output
origin (0,0)
middle (50,50)
corner (100,100)

typedef — Dropping the struct Keyword

In simple words: C insists on struct Student s;, which gets tedious. A typedef gives the type a second, shorter name so you can write Student s; instead.
Example05
CCode Cell
1#include <stdio.h>
2 
3/* Form 1: anonymous struct + typedef name */
4typedef struct {
5 char name[30];
6 float price;
7} Book;
8 
9/* Form 2: keep the tag AND add a typedef name */
10typedef struct Employee {
11 int id;
12 float salary;
13} Employee;
14 
15int main()
16{
17 Book b = {"C Primer", 450.0f}; /* no struct keyword */
18 Employee e = {7, 62000.0f};
19 struct Employee e2 = {8, 55000.0f}; /* the tag still works */
20 
21 printf("%s Rs %.2f\n", b.name, b.price);
22 printf("#%d Rs %.2f\n", e.id, e.salary);
23 printf("#%d Rs %.2f\n", e2.id, e2.salary);
24 return 0;
25}
Output
C Primer Rs 450.00
#7 Rs 62000.00
#8 Rs 55000.00

Keep the Tag When You Need Self-Reference

An anonymous typedef has no name to refer to inside its own body. For a linked list you need either the tag or a forward typedef:

Example06
CCode Cell
1#include <stdio.h>
2 
3/* BROKEN: 'Node' does not exist yet inside the braces
4typedef struct {
5 int data;
6 Node *next; <- error: unknown type name
7} Node;
8*/
9 
10/* WORKS: the tag is visible immediately */
11typedef struct Node {
12 int data;
13 struct Node *next; /* refer to it by tag */
14} Node;
15 
16int main()
17{
18 Node third = {3, NULL};
19 Node second = {2, &third};
20 Node first = {1, &second};
21 
22 for (Node *p = &first; p != NULL; p = p->next)
23 printf("%d ", p->data);
24 printf("\n");
25 return 0;
26}
Output
1 2 3 

A Structure Cannot Contain Itself

A member of the same type would need infinite size. A pointer to the same type is fine — its size is known:

Example07
CCode Cell
1#include <stdio.h>
2 
3/* ILLEGAL - infinite size
4struct Bad {
5 int data;
6 struct Bad next; <- error: field has incomplete type
7};
8*/
9 
10struct Good {
11 int data;
12 struct Good *next; /* a pointer is always 8 bytes */
13};
14 
15int main()
16{
17 printf("sizeof(struct Good) = %zu\n", sizeof(struct Good));
18 printf(" int data : %zu bytes\n", sizeof(int));
19 printf(" pointer : %zu bytes\n", sizeof(struct Good *));
20 return 0;
21}
Output
sizeof(struct Good) = 16
  int data  : 4 bytes
  pointer   : 8 bytes

Where to Declare — Scope

A structure declared inside a function is only usable there. Declare at file scope so every function can see the type:

Example08
CCode Cell
1#include <stdio.h>
2 
3/* File scope - visible to every function below */
4struct Point { int x, y; };
5 
6void show(struct Point p) /* can name the type */
7{
8 printf("(%d, %d)\n", p.x, p.y);
9}
10 
11int main()
12{
13 struct Local { int a; }; /* only exists inside main */
14 struct Local l = {5};
15 
16 struct Point p = {10, 20};
17 show(p);
18 printf("Local a = %d\n", l.a);
19 return 0;
20}
Output
(10, 20)
Local a = 5

Nested Declarations

One structure can contain another. Declaring the inner type separately keeps it reusable:

Example09
CCode Cell
1#include <stdio.h>
2 
3struct Date {
4 int day, month, year;
5};
6 
7struct Employee {
8 int id;
9 char name[30];
10 struct Date joined; /* a Date inside an Employee */
11 struct Date reviewed; /* reusable */
12};
13 
14int main()
15{
16 struct Employee e = {7, "Kavya", {15, 6, 2021}, {1, 4, 2024}};
17 
18 printf("#%d %s\n", e.id, e.name);
19 printf("Joined : %d/%d/%d\n",
20 e.joined.day, e.joined.month, e.joined.year);
21 printf("Reviewed : %d/%d/%d\n",
22 e.reviewed.day, e.reviewed.month, e.reviewed.year);
23 return 0;
24}
Output
#7 Kavya
Joined   : 15/6/2021
Reviewed : 1/4/2024

Declaring in a Header File

In real projects the definition goes in a .h file so several .c files can share it. Include guards stop double inclusion:

Example10
CCode Cell
1/* ---------- student.h ---------- */
2#ifndef STUDENT_H
3#define STUDENT_H
4 
5typedef struct {
6 char name[30];
7 int roll;
8 float marks;
9} Student;
10 
11void printStudent(Student s); /* prototype, not the body */
12 
13#endif
14 
15/* ---------- student.c ---------- */
16#include <stdio.h>
17#include "student.h"
18 
19void printStudent(Student s)
20{
21 printf("%-10s %d %.1f\n", s.name, s.roll, s.marks);
22}
23 
24/* ---------- main.c ---------- */
25#include "student.h"
26 
27int main()
28{
29 Student s = {"Rahul", 101, 85.5f};
30 printStudent(s);
31 return 0;
32}
Output
Rahul      101  85.5

Common Mistakes

  • Missing the semicolon after } — the error appears on the following line.
  • Omitting the struct keywordStudent s; without a typedef is an error in C.
  • A member of the structure's own type — use a pointer instead.
  • Self-reference in an anonymous typedef — keep the tag.
  • Declaring inside a function — the type is then invisible to other functions.
  • Assigning initial values to members in the definition — C has no default member initialisers; initialise the variable instead.
Trainer's Note: the semicolon after } is there because a structure definition is a declaration statement — the same reason int x; needs one. That is also why you may squeeze variable names in between } and ;.
📝 Key Takeaways
  • Syntax: struct Tag { members }; — the closing semicolon is required.
  • A definition is a blueprint; it allocates no memory.
  • typedef struct { ... } Name; lets you write Name instead of struct Name.
  • Declare at file scope so every function can use the type.
  • A structure may contain a pointer to its own type, but not itself.

🧠 Test Your Knowledge

4 Questions
Progress: 0 / 4