C++: References

Last updated: 2026-08-26

Pointers are powerful, but somewhat cumbersome — you need to write *p to dereference, and watch out for null pointers.

C++ introduced references — "aliases" for variables that are safer and simpler to use than pointers.



1. What is a Reference?

(1) 1.1 References in Everyday Life

Real-life Analogy Program Equivalent
You have a nickname "Xiaoming" — calling either name finds you Reference (alias for a variable)
The name on your ID card vs. your everyday name Reference and the original variable

Essence of a reference: A reference is an alias for a variable — operating on the reference is operating on the referenced variable.

(2) 1.2 Why Do We Need References?

Using pointers (cumbersome):

▶ Example 2: Code Example (Difficulty ⭐)

CPP
#include <iostream>

void modifyValue(int* x) {
 *x = 100; // Need dereference
}

int main() {
 int a = 5;
 modifyValue(&a); // Need to pass address
 std::cout << a << std::endl; // 100
 return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
(Program output)

Using references (simple):

CPP
#include <iostream>

void modifyValue(int& x) { // x Is a reference
 x = 100; // Use directly,No dereference needed
}

int main() {
 int a = 5;
 modifyValue(a); // Looks like pass by value,Actually pass by reference
 std::cout << a << std::endl; // 100
 return 0;
}


2. Reference Declaration and Initialization

(1) 2.1 Declaring a Reference

Syntax:

TEXT 📖 Display only
Type& Reference name = originalVariable;

Example:

CPP
#include <iostream>

int main() {
 int x = 5;
 int& ref = x; // ref is alias of x
 
 std::cout << "x = " << x << std::endl; // 5
 std::cout << "ref = " << ref << std::endl; // 5
 
 ref = 100; // modifying ref modifies x
 std::cout << "After modification x = " << x << std::endl; // 100
 
 return 0;
}

💡 Key point: References must be initialized — you cannot declare first and assign later.


(2) 2.2 References vs Pointers

Comparison Reference Pointer
Syntax int& ref = x; int* p = &x;
Can be null? ❌ No (must initialize) ✅ Yes (nullptr)
Need dereferencing? ❌ No (use directly) ✅ Yes (*p)
Can rebind? ❌ No (once bound, cannot change) ✅ Yes (can point to another variable)
Recommendation ⭐⭐⭐⭐⭐ (prefer) ⭐⭐⭐ (use when necessary)


3. References as Function Parameters*

(1) 3.1 Basic Usage

CPP
#include <iostream>

// Use reference parameters to "return" multiple values
void minMax(int arr, int length, int& min, int& max) {
 min = arr[0];
 max = arr[0];
 
 for (int i = 1; i < length; i++) {
 if (arr[i] < min) {
 min = arr[i];
 }
 if (arr[i] > max) {
 max = arr[i];
 }
 }
}

int main() {
 int arr[5] = {3, 1, 4, 1, 5};
 int min, max;
 
 minMax(arr, 5, min, max); // min and max will be modified
 
 std::cout << "Minimum: " << min << std::endl; // 1
 std::cout << "Maximum: " << max << std::endl; // 5
 
 return 0;
}

💡 Key point: Reference parameters allow functions to "return" multiple values (by modifying multiple reference parameters).


(2) 3.2 const References (Most Commonly Used)

If you don't want the function to modify the parameter, but still want to avoid the cost of copying, use a const reference.

CPP
#include <iostream>
#include <string>

void printName(const std::string& name) { // const reference: Cannot modify name
 std::cout << "Name: " << name << std::endl;
 // name = "Alice"; // ❌ Error: Cannot modify const reference
}

int main() {
 std::string myName = "MOTO";
 printName(myName); // No need to copy entire string, more efficient
 return 0;
}

💡 Golden rule: Prefer const references for function parameters — balancing safety and efficiency.



4. Pitfalls of References*

(1) 4.1 References Must Be Initialized*

CPP
#include <iostream>

int main() {
 int& ref; // ❌ Error: Reference requires initialization
 return 0;
}

Compiler error message:

TEXT 📖 Display only
error: 'ref' declared as reference but not initialized

(2) 4.2 References Cannot Be Rebound*

CPP
#include <iostream>

int main() {
 int x = 5;
 int y = 10;
 int& ref = x;
 
 ref = y; // ❌ This is NOT rebinding! This changes x's value to y's value
 std::cout << "x = " << x << std::endl; // 10
 std::cout << "y = " << y << std::endl; // 10
 
 return 0;
}

💡 Key point: Once a reference is bound to a variable, it cannot be rebound to another variable.



5. Practice: Multiple Return Values*

▶ Example 1: Calculating Quotient and Remainder (Difficulty ⭐⭐)

CPP
#include <iostream>

// Use reference parameters to "return" multiple values
void divide(int a, int b, int& quotient, int& remainder) {
 quotient = a / b;
 remainder = a % b;
}

int main() {
 int a = 17, b = 5;
 int q, r;
 
 divide(a, b, q, r); // q and r will be modified
 
 std::cout << a << " / " << b << " = " << q << " ... " << r << std::endl;
 // Output:17 / 5 = 3 ... 2
 
 return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
 /  =  ... 

▶ Example 3: Reference as Function Return Value (Difficulty ⭐)

CPP
#include <iostream>
#include <string>

std::string name = "Zhang San"; // Global variable

// Return reference (not value)
std::string& getName() {
    return name; // Returns a reference to name
}

int main() {
    getName() = "Li Si"; // Modify global variable
    
    std::cout << "name = " << name << std::endl;
    
    return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
name = 
💡 Tip: Returning a reference from a function allows the return value to be used as an lvalue. But beware: never return a reference to a local variable!


❓ FAQ

Q: What's the real difference between references and pointers? A:> - References are aliases for variables; pointers are variables that store addresses > - References must be initialized; pointers can be nullptr > - References cannot be rebound; pointers can > - Prefer references unless you need to represent "nothing" (then use pointers) Q: Why can't arrays be passed by reference as parameters? A: They can, but the syntax for array references is complex.

Simpler approach: Use std::array or std::vector (covered later).

Q: Do references improve runtime efficiency? A: No. References are typically implemented as pointers under the hood, so runtime efficiency is the same.

What they improve is development efficiency (code is cleaner, less error-prone).


Q: What's the most important thing about references? A: Understand the core concepts first, then reinforce them through practice examples.


📖 Summary


📝 Exercises

  1. Basic (Difficulty ⭐): Write a function void addTen(int& x) that adds 10 to the passed variable. Test it in main.

  2. Intermediate (Difficulty ⭐⭐): Write a function void swap(int& a, int& b) that swaps two variables' values. Test it in main.

  3. Challenge (Difficulty ⭐⭐⭐): Write a program that implements "sort three numbers":

  4. Write a function void sortThree(int& a, int& b, int& c) that sorts three numbers in ascending order

  5. In main, let the user enter three numbers, call sortThree, then output the sorted result

6. 🚀 Next Step*

Now that you've learned references, let's move on to Dynamic Memory Allocation (Lesson 26) — managing memory manually with new and delete, and understanding the difference between the stack and the heap.

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏