Exercises — Typedef
Remember the one trick that unlocks every problem (from Typedef):
Level 1 — Recognition
Goal: can you spot what a typedef names, without running anything?
L1.1
typedef unsigned char Byte;Q: What existing type does Byte name?
Recall Solution
Cover typedef → unsigned char Byte; declares a variable Byte of type unsigned char.
Therefore Byte is an alias for ==unsigned char==.
A smaller sanity check: unsigned char holds values to (that is ), which is why "Byte" is a fitting nickname.
L1.2
typedef double Real;
Real pi = 3.14;Q: After this, is Real pi = 3.14; legal, and what is pi's real type?
Recall Solution
Yes, legal. Real is double, so Real pi = 3.14; is identical to double pi = 3.14;.
typedef creates a name, not a new kind of thing — pi is a plain double.
L1.3
typedef char *String;Q: Is String an alias for char, or for char *?
Recall Solution
Cover typedef → char *String;. The * binds to the name String, not to char. So String would be a variable of type char *.
Therefore String = ==char *== (pointer to char), not char.
Level 2 — Application
Goal: use a typedef to write shorter, correct code.
L2.1
Given:
struct Point { int x, y; };
typedef struct Point Point;Q: Write a line declaring a Point called p and setting p.x = 3, p.y = 4.
Recall Solution
Point p;
p.x = 3;
p.y = 4;Why this works: without the alias you'd need struct Point p; because in C the struct tag Point lives in a separate namespace. The typedef puts Point into the ordinary type namespace, so you may drop the struct keyword. See Structures in C.
L2.2
typedef int* IntPtr;
IntPtr a, b;Q: What are the types of a and b?
Recall Solution
Both a and b are int*.
The * is baked inside the alias IntPtr. When you write IntPtr a, b; each variable independently gets the whole aliased type. So a is int* and b is int*.
L2.3
typedef unsigned int uint;
uint x = 5;
uint y = 4294967295; /* 2^32 - 1 */Q: On a system where unsigned int is 32 bits, what is x + 1 and what is y + 1?
Recall Solution
uint is unsigned int, so arithmetic wraps around modulo .
x + 1 = 6.- The value is the largest representable value, so
y + 1wraps back to . The alias changed nothing about behaviour — it is stillunsigned int.
Level 3 — Analysis
Goal: predict differences and explain why.
L3.1
#define INTPTR int*
typedef int* IntPtr;
INTPTR a, b;
IntPtr c, d;Q: Classify each of a, b, c, d as int or int*.
Recall Solution
#define is dumb text replacement by the preprocessor. INTPTR a, b; literally becomes:
int* a, b; // a is int*, b is intSo a = int*, b = int.
typedef is a real type alias understood by the compiler. IntPtr c, d; gives each variable the whole type:
c=int*,d=int*.
Summary: a = int*, b = int, c = int*, d = int*. This is the crucial typedef vs #define split from Pointers in C.
L3.2
Decode this declaration using the cover-typedef trick:
typedef int (*Operation)(int, int);Q: What type is Operation?
Recall Solution
Cover typedef → int (*Operation)(int, int);.
Read the declarator from the identifier outward:
Operationis the name.(*Operation)— the parentheses force*to bind first:Operationis a pointer to something.(...)(int, int)— that something is a function taking(int, int).- The leading
intis the return type.
Therefore Operation = "pointer to a function taking two ints and returning int". See Function Pointers.
L3.3
typedef int Money;
Money price = 100; // 100 rupeesLater the project needs cents (fractions), so someone changes the alias to:
typedef double Money;Q: How many lines of usage code must change, and what value does Money price = 100; now hold?
Recall Solution
Zero usage lines change — that is the whole point of portability. Only the single typedef line changed.
After the change Money is double, so Money price = 100; stores 100.0 (a double). price / 3 now gives a fractional result instead of the truncated integer 33.
This shows why aliasing a policy type (like "how we store money") behind one name is powerful: change once, everything follows.
Level 4 — Synthesis
Goal: build multi-piece type designs yourself.
L4.1
Q: Write a typedef for an array of 4 Operations (using Operation from L3.2), giving the array type its own alias OperationTable4. Then show how to call the third stored operation on (2, 3).
Recall Solution
typedef int (*Operation)(int, int); // from L3.2
typedef Operation OperationTable4[4]; // NEW alias: array of 4 Operations
OperationTable4 table; // 'table' is an array of 4 function pointers
// suppose table[2] = add; where int add(int,int){...}
int r = table[2](2, 3); // calls add(2,3)How to read the new typedef: cover typedef → Operation OperationTable4[4]; declares OperationTable4 as an array of 4 Operations. So the identifier OperationTable4 becomes the alias, and its meaning is "array of 4 function pointers".
Why the alias earns its keep: without any alias, this type is written int (*table[4])(int, int); — nearly unreadable. With the two typedefs, OperationTable4 table; reads like plain English. The third stored operation is table[2]; calling add(2,3) where int add(int a,int b){return a+b;} yields ==5==.
L4.2
Q: Using an anonymous struct, write a single typedef that makes Vec2 a type with float x, y;. Then declare Vec2 v = {1.5f, 2.5f}; and compute v.x + v.y.
Recall Solution
typedef struct { float x, y; } Vec2;
Vec2 v = {1.5f, 2.5f};
float s = v.x + v.y; // s = 4.0Why anonymous? We never need to refer to the struct by a tag, only by the alias Vec2, so we skip naming the tag entirely. v.x + v.y = 1.5 + 2.5 = ==4.0==. See Structures in C.
L4.3
Q: For a linked list, write the typedef so that Node means struct node, allowing a self-referential pointer next. Then state what sizeof(Node) roughly contains on a 64-bit system (assume int = 4 bytes, pointer = 8 bytes, before padding).
Recall Solution
typedef struct node {
int data;
struct node *next; // must use the TAG here, alias not visible yet
} Node;Why the tag node is still needed: inside the struct body the alias Node does not exist yet (the typedef name is only usable after the closing brace), so the self-reference must use struct node *.
Raw member sizes: int data = 4 bytes, struct node *next = 8 bytes → 12 bytes of data. With alignment, the compiler pads to a multiple of 8, giving sizeof(Node) = 16 bytes. See Linked Lists and Pointers in C.
Level 5 — Mastery
Goal: reason at the edge — degenerate and tricky cases.
L5.1
Q: Is the following legal, and if so what does it do?
typedef int Integer;
typedef Integer Whole;
Whole n = 7;Recall Solution
Legal. A typedef may alias another alias. Chain: Whole → Integer → int. So Whole n = 7; is just int n = 7;. Aliasing is transitive; there is no "new type" at any step, only names pointing at int.
L5.2
Q: Given
typedef int Arr[3];
Arr a;what is the type of a, and what is sizeof(a) (with 4-byte int)?
Recall Solution
Cover typedef → int Arr[3]; declares Arr as an array of 3 ints. So the alias Arr means "array of 3 int". Arr a; therefore makes a an array of 3 int.
sizeof(a) = 3 × 4 = ==12== bytes.
This is the surprising power (and danger) of array typedefs: the array-ness is hidden inside the name.
L5.3
Q: With typedef int Arr[3];, consider a function void f(Arr x). Does x inside f behave as an array of 3 ints, or as a pointer? What is sizeof(x) inside f on a 64-bit system?
Recall Solution
A degenerate/edge case. In C, any array parameter — even one hidden behind a typedef — decays to a pointer. So void f(Arr x) is really void f(int *x).
Inside f, x is a pointer, so sizeof(x) = ==8== bytes (pointer size on 64-bit), not 12.
Lesson: the alias hides the array type, but the array-to-pointer decay rule still applies at function boundaries — the name did not change the language's behaviour, only its spelling.
How the levels build
The ladder is deliberate — each level reuses the rung below and adds exactly one new idea:
| Level | New idea it adds | The one thing you must carry up |
|---|---|---|
| L1 Recognition | Spot what an alias names | An alias is a name, nothing more |
| L2 Application | Use the alias (struct, pointer, wraparound) |
Behaviour = the underlying type's behaviour |
| L3 Analysis | typedef vs #define |
Compiler alias ≠ text substitution |
| L4 Synthesis | Build fn-ptr arrays, structs, list nodes | Aliases can nest and self-reference |
| L5 Mastery | Array aliases, chains, parameter decay | The name never changes language rules |
Recall
One rule that survives every level ::: typedef makes a name, never a new type — behaviour (wraparound, decay, size) is exactly that of the underlying type.
Why Arr x as a parameter has size 8 not 12 ::: array parameters decay to pointers in C, even through a typedef.
Connections
- Typedef — parent note (theory these exercises drill).
- Structures in C · Pointers in C · Function Pointers · Linked Lists — the real types we aliased.
- 🇮🇳 5.1.26 Typedef (Hinglish)