Review the key points with a cheat sheet, six code-reading questions, and a checklist of common mistakes.
int x = 5; int *p = &x; // p holds x's address printf("%d\n", *p); // 5 (read the pointed-to value) *p = 100; // x also becomes 100!
* is part of a declaration; *p = 5in * dereferences a pointer struct Point { int x, y; }; struct Point p = { 3, 4 }; printf("%d %d\n", p.x, p.y); // 3 4 struct Point *pp = &p; printf("%d\n", pp->x); // 3 (-> is shorthand for (*pp).x)
.; for a pointer use ->#include <stdlib.h> int *a = malloc(sizeof(int) * 10); if (a == NULL) { /* Allocation failed */ } a[0] = 42; free(a); // Release the memory! a = NULL; // Help prevent accidental double-free through this variable
NULL is returned FILE *fp = fopen("data.txt", "r"); if (fp == NULL) { /* Could not open the file */ } int n; fscanf(fp, "%d", &n); fclose(fp); // Close the file!
| Symbol | Meaning | Example |
|---|---|---|
| & | AND | 5 & 3 → 1 |
| | | OR | 5 | 3 → 7 |
| ^ | XOR | 5 ^ 3 → 6 |
| ~ | Complement | ~5 → -6 |
| << | Left shift | 1 << 3 → 8 |
| >> | Right shift | 8 >> 2 → 2 |
(n & 1) == 0n << 1 / n >> 1&&and bitwise &operators differ int x = 10; int *p = &x; *p = 99; printf("%d\n", x);
99. This allows a function to change a caller-owned object through its address.void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } int x = 3, y = 7; swap(&x, &y); printf("%d %d\n", x, y);
7 3. Passing values alone would swap only local copies; addresses let swap modify the originals.struct Point { int x, y; }; struct Point p = {10, 20}; struct Point *pp = &p; pp->x = 99; printf("%d %d\n", p.x, p.y);
pp->x means (*pp).x. Because pp points to p, assigning pp->x=99 changes p.x. The output is 99 20. Use -> for member access through a structure pointer.#include <stdlib.h> int *a = malloc(sizeof(int) * 3); a[0] = 10; a[1] = 20; a[2] = 30; int sum = a[0] + a[1] + a[2]; free(a); printf("%d\n", sum);
60. Reading a[0] after free would instead be undefined behavior.for (int n = 1; n <= 5; n++) { if ((n & 1) == 0) printf("%d ", n); }
n & 1 extracts the lowest bit. For these positive integers, (n & 1) == 0 identifies even numbers, printing 2 4. The test n%2==0 is equivalent here; modern compilers can optimize either form.struct P { int x, y; }; struct P a = {1, 2}; struct P b = a; // Copy b.x = 99; printf("%d %d %d %d\n", a.x, a.y, b.x, b.y);
1 2 99 2. Pointer members would be shallow-copied, but these members are integers.int *p; *p = 5; leaves p without a valid target, causing undefined behavior when dereferenced. Initialize it to NULL or a valid address. freeused a pointer after releasing its target (use-after-free) p = NULL prevents accidental reuse through that variable; other aliases still need care. if(fp == NULL). .and ->were confused p.x; for a pointer use pp->x. pp.x causes a compilation error. &&and bitwise &operators (a == 1) & (b == 2)may appear to work because the comparisons yield truth values, but it lacks short-circuit evaluation. Combine conditions with &&.
&and *Review the meaning of
Quiz (Pointers) Check understanding with related questions
Structs (struct) Review . and -> member access
Lesson 40: Unions Review shared memory for members
Lesson 41: File input and output Review fopen, fclose, and file modes
Lesson 42: Dynamic memory Review malloc, free, and NULL checks
Bitwise Operators Review shifts, AND, OR, and XOR
Cheat sheet Review pointers, structures, and malloc on one page