Pointers and Basic Pointer Syntax, CS1 – Study Notes
offline

Difficulty: Intermediate | Prerequisites: C variables, data types, functions, memory fundamentals (bits, bytes, sizeof)


Big Picture

Pointers are one of the defining features of C. They give you direct access to memory addresses, which is powerful but comes with responsibility: you can create subtle, hard-to-find bugs if you mishandle them. This topic is the gateway to dynamic memory allocation, pass-by-reference, and data structures like linked lists. If you skipped the memory fundamentals (bits, bytes, addresses), go back and cover those first, because nothing here will make sense without that foundation.


TL;DR

A pointer is a variable that stores a memory address. The & operator gets the address of a variable; the * operator dereferences a pointer to access the value at that address. Pointers enable pass-by-reference, efficient data sharing between functions, and dynamic memory allocation.


Key Terms

Pointer

A variable whose value is the memory address of another variable. Think of it as a sticky note that says "the thing you want is in locker number 1000" rather than holding the thing itself.

Dereference operator (*)

When applied to a pointer, retrieves the value stored at the memory location the pointer holds. In simple terms, it means "go to the address this pointer is pointing at and give me what is there."

Address-of operator (&)

Returns the memory address where a variable is stored. In simple terms, it answers "where in memory does this variable live?"

L-value

An internal memory location capable of storing data. Every l-value has an address, and that address never changes once the variable is declared. Think of it as anything that can appear on the left side of an assignment: it names a place in memory you can write to.

NULL pointer

A pointer that is explicitly set to point at nothing. Dereferencing a NULL pointer causes a runtime error (segmentation fault). In simple terms, it is the pointer equivalent of "this slot is empty."

Pass by value

The function receives a copy of the argument. Changes inside the function do not affect the original variable.

Pass by reference (via pointers)

The function receives the address of the argument. Changes made through the pointer do affect the original variable.


Core Content

Why C Has Pointers

  • The designers of C wanted programmers to manipulate memory directly. Languages like Java hide this from you; C does not.

  • More control comes with more responsibility: you must manage memory yourself.

Four main reasons to use pointers:

  • Refer to a large data structure compactly (pass an address instead of copying the entire thing)

  • Share data efficiently among functions

  • Dynamically reserve memory at runtime

  • Record relationships between data (linked lists, trees)


L-Value Rules

  • Every l-value is stored somewhere in memory and has an address.

  • Once declared, the address of an l-value never changes.

  • Different l-values can require different amounts of memory (an int uses 4 bytes, a char uses 1).

  • The address of an l-value is a pointer value.


Declaring and Using Pointers

Declaration:

int *p;

This declares p as a pointer to an int. The pointer itself stores an address, not an integer value.

The two key operators:

  • *p – dereference: read or write the value at the address p holds

  • &x – address-of: get the memory address of variable x

Trace-through example:

int x, y;
int *p1, *p2;
x = -42;
y = 163;
p1 = &x;       // p1 points to x
p2 = &y;       // p2 points to y
*p1 = 17;      // x is now 17 (written through p1)
p1 = p2;       // p1 now points to y (same as p2)
p2 = &x;       // p2 now points to x
*p1 = *p2;     // y = x, so y is now 17

After this code runs: x = 17, y = 17, p1 points to y, p2 points to x.

Setting a pointer to NULL:

p = NULL;

This signals that the pointer is not currently pointing at any valid data. Always check before dereferencing.


Pass by Value vs. Pass by Reference

This is one of the most commonly tested pointer concepts.

swap1 (pass by value, does not work):

void swap1(int x, int y) {
    int temp;
    temp = x;
    x = y;
    y = temp;
}
  • The function receives copies of the arguments. It swaps the copies. The originals in the calling function are unchanged.

swap2 (pass by reference via pointers, works correctly):

void swap2(int *p1, int *p2) {
    int temp;
    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}
  • The function receives addresses. It dereferences those addresses to read and write the original variables directly.

  • You would call this as: swap2(&a, &b);


Real-World Applications

Every time you pass a large struct to a function in a real C programme, you pass a pointer to it rather than copying the entire struct. Device drivers, operating system kernels, and embedded firmware all rely on pointers to interact with hardware registers at specific memory addresses.


Common Misconceptions

  • Students often confuse the in a declaration (int p;) with the dereference operator (*p = 5;). In the declaration, it means "p is a pointer." Everywhere else, it means "go to the address p holds."

  • Students frequently expect swap1 to work. It does not, because C passes arguments by value. If the exam shows you a swap function without pointers, the answer is that the originals are not modified.

  • Students sometimes forget to initialise pointers before using them. An uninitialised pointer holds garbage, and dereferencing it is undefined behaviour.

  • Dereferencing a NULL pointer does not return zero. It crashes the programme with a runtime error.


Why It Matters / Exam Flags

⚠️ Be able to trace through pointer code step by step, tracking the values of both the pointers and the variables they point to.

⚠️ Know why swap1 fails and swap2 works. This is a classic exam question.

⚠️ Understand that dereferencing NULL or an uninitialised pointer is a runtime error, not a compile-time error.

⚠️ Know the difference between assigning a pointer (p1 = p2, both point to the same place) and assigning through a pointer (*p1 = *p2, copy the value from one location to another).


Quick Self-Test

  1. True or false: int *p; allocates memory for an integer.

  1. Fill in the blank: The operator & returns the ______ of a variable.

  1. True or false: After p1 = p2;, changing p1 also changes p2.

  1. Fill in the blank: Dereferencing a NULL pointer causes a ______ error.

  1. True or false: swap1(a, b) modifies the values of a and b in the calling function.


Practice Q&A

Q: After the code int x = 5; int p = &x; p = 10;, what is the value of x?

A: 10. The pointer p holds the address of x, and *p = 10 writes 10 directly to that address.

Q: Why does swap1 fail to swap the values of its arguments in the calling function?

A: Because C is pass-by-value. swap1 receives copies of the arguments. It swaps the copies inside the function, but the original variables in the calling function are never touched.

Q: What happens if you write *p = 7; when p is set to NULL?

A: You get a runtime error (segmentation fault). NULL is not a valid memory address, so dereferencing it is undefined behaviour that typically crashes the programme.

Q: Given int a = 3, b = 7; int p1 = &a, p2 = &b;, what are the values of a and b after p1 = p2;?

A: a = 7, b = 7. The value at the address p2 holds (which is b, value 7) is copied to the address p1 holds (which is a).

Q: How do you correctly call swap2 to swap variables a and b?

A: swap2(&a, &b); – you pass the addresses of a and b.


Connections to Other Topics

Pointers are the prerequisite for arrays (an array name is a pointer to its first element), structs accessed via ->, and all dynamic memory allocation with malloc/calloc/free. They also underpin linked lists, trees, and every non-trivial data structure you will build in later courses.


Related Terms / Search Tags

pointer, C pointer, dereference, address-of operator, ampersand, asterisk, l-value, lvalue, NULL, null pointer, pass by value, pass by reference, swap function, pointer syntax, pointer declaration, segmentation fault, CS1, Computer Science I, UCF