C Notes
Learn how to declare and initialize pointers in C using * and & operators, pointer types, multiple pointer declarations, and const pointers with examples.
Declaring and initializing pointers correctly is the first step to mastering them. The syntax can look confusing at first — especially with the * symbol being used in both declaration and dereferencing — but once you understand the logic, it becomes second nature.
Pointer Declaration Syntax
The general form of a pointer declaration is:
data_type *pointer_name;The * in the declaration tells the compiler that this variable will hold an address to a value of the specified data type.
int *p; // Pointer to integer
float *fptr; // Pointer to float
char *cptr; // Pointer to character
double *dptr; // Pointer to doubleWhere to Place the Asterisk
All three styles are equivalent — the choice is purely stylistic:
Warning: Style 2 can be misleading with multiple declarations: ``c int* p, q; // p is a pointer, but q is just an int! int *p, *q; // Both are pointers (clearer) ``Initialization with the Address-of Operator (&)
A pointer must be initialized with a valid address before use. The & operator returns the address of a variable:
#include <stdio.h>
int main() {
int x = 10;
int *p = &x; // p now stores the address of x
printf("x = %d\n", x);
printf("&x = %p\n", (void*)&x);
printf("p = %p\n", (void*)p);
printf("*p = %d\n", *p);
return 0;
}x = 10 &x = 0x7ffc3a2b1c4d p = 0x7ffc3a2b1c4d *p = 10
The Dereference Operator (*)
The * operator (when used on a pointer, not in declaration) accesses the value at the stored address:
#include <stdio.h>
int main() {
int a = 50;
int *ptr = &a;
printf("Direct access: a = %d\n", a);
printf("Through pointer: *ptr = %d\n", *ptr);
// Modify through pointer
*ptr = 75;
printf("\nAfter *ptr = 75:\n");
printf("a = %d\n", a); // a is now 75!
printf("*ptr = %d\n", *ptr); // Same value
return 0;
}Direct access: a = 50 Through pointer: *ptr = 50 After *ptr = 75: a = 75 *ptr = 75
Memory Diagram: Step by Step
| Step 1 | Variable 'a' is created |
| Address | 0x100 |
| Step 2 | Pointer 'ptr' stores address of 'a' |
| Address | 0x200 |
| ptr │ 0x100 ─┼──────── | │ 50 │ a |
| Step 3 | *ptr = 75 (write 75 to address stored in ptr) |
| ptr │ 0x100 ─┼──────── | │ 75 │ a (modified!) |
Pointer Types and Type Safety
The pointer type determines how many bytes are read/written during dereferencing:
#include <stdio.h>
int main() {
int i = 42;
float f = 3.14;
char c = 'A';
int *ip = &i; // Points to 4-byte integer
float *fp = &f; // Points to 4-byte float
char *cp = &c; // Points to 1-byte character
printf("*ip = %d (reads %lu bytes)\n", *ip, sizeof(*ip));
printf("*fp = %.2f (reads %lu bytes)\n", *fp, sizeof(*fp));
printf("*cp = %c (reads %lu byte)\n", *cp, sizeof(*cp));
return 0;
}*ip = 42 (reads 4 bytes) *fp = 3.14 (reads 4 bytes) *cp = A (reads 1 byte)
Type Mismatch Warning
int x = 100;
float *fp = &x; // WARNING: incompatible pointer type!
// *fp will misinterpret the integer bits as a float valueMultiple Pointer Declarations
Be careful when declaring multiple pointers on one line:
// CORRECT: Both are pointers
int *p1, *p2;
// WRONG: Only p1 is a pointer, p2 is an int!
int *p1, p2;
// Using typedef for clarity
typedef int* IntPtr;
IntPtr a, b; // Both a and b are int pointersPointer Reassignment
A pointer can be redirected to point to a different variable:
#include <stdio.h>
int main() {
int x = 10, y = 20;
int *ptr = &x;
printf("ptr points to x: *ptr = %d\n", *ptr);
ptr = &y; // Now pointing to y
printf("ptr points to y: *ptr = %d\n", *ptr);
*ptr = 30; // Modifies y
printf("y is now: %d\n", y);
return 0;
}ptr points to x: *ptr = 10 ptr points to y: *ptr = 20 y is now: 30
Const Pointers
The const keyword can be applied to pointers in different ways:
Pointer to Constant (Data is read-only)
const int *ptr; // Cannot modify the VALUE through ptr
// or equivalently:
int const *ptr;int x = 10, y = 20;
const int *ptr = &x;
// *ptr = 15; // ERROR: cannot modify value
ptr = &y; // OK: can change where ptr pointsConstant Pointer (Address is fixed)
int *const ptr = &x; // Cannot change WHERE ptr pointsint x = 10, y = 20;
int *const ptr = &x;
*ptr = 15; // OK: can modify value
// ptr = &y; // ERROR: cannot change the addressConstant Pointer to Constant (Both fixed)
const int *const ptr = &x; // Cannot change anythingint x = 10;
const int *const ptr = &x;
// *ptr = 15; // ERROR
// ptr = &y; // ERRORConst Pointer Summary Table
| Declaration | Modify Value (*ptr)? | Modify Address (ptr)? |
|---|---|---|
int *ptr | ✅ Yes | ✅ Yes |
const int *ptr | ❌ No | ✅ Yes |
int *const ptr | ✅ Yes | ❌ No |
const int *const ptr | ❌ No | ❌ No |
Reading trick: Read the declaration right-to-left. const int *ptr → "ptr is a pointer to int that is const" (the int value is const). int *const ptr → "ptr is a const pointer to int" (the pointer itself is const).
Practical Example: Swapping Values
The classic demonstration of why pointers are needed:
#include <stdio.h>
// This does NOT work — parameters are copies
void swapWrong(int a, int b) {
int temp = a;
a = b;
b = temp;
}
// This WORKS — using pointers to modify original variables
void swapRight(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
printf("Before swap: x=%d, y=%d\n", x, y);
swapWrong(x, y);
printf("After swapWrong: x=%d, y=%d\n", x, y); // No change!
swapRight(&x, &y);
printf("After swapRight: x=%d, y=%d\n", x, y); // Swapped!
return 0;
}Before swap: x=5, y=10 After swapWrong: x=5, y=10 After swapRight: x=10, y=5
Interview Questions
**Q1: What's the difference between *p in declaration vs. in expression?**
In declaration (int *p;), the * simply indicates that p is a pointer type. In expression (x = *p;), the * is the dereference operator that accesses the value at the address stored in p.
Q2: What is a dangling pointer?
A pointer that holds the address of memory that has been freed (deallocated) or a local variable that has gone out of scope. Dereferencing a dangling pointer causes undefined behavior. Always set pointers to NULL after freeing.
Q3: Why do we need pointer types if all pointers are the same size?
The type tells the compiler: (1) how many bytes to read/write when dereferencing, (2) how to interpret those bytes, and (3) how much to advance during pointer arithmetic. An int* advances 4 bytes per increment; a char* advances 1 byte.
Q4: Can a pointer point to another pointer?
Yes, these are called double pointers (int **pp). They store the address of a pointer variable and are used for dynamically allocated 2D arrays and for modifying pointer values inside functions.
Summary
- Declare pointers with
data_type *name;— the*indicates pointer type - Initialize with
&variableto get the address of a variable - Dereference with
*pointerto access/modify the value at the stored address - Pointer type determines byte count and interpretation during dereferencing
- Use
constappropriately:const int *p(read-only data) vsint *const p(fixed address) - Always initialize pointers before use — uninitialized pointers are dangerous
- In multi-variable declarations, each pointer needs its own
*
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Pointer Declaration and Initialization in C.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, pointers, pointer, declaration, pointer declaration and initialization in c
Related C Programming Topics