Table of contents
1--The basic grammar of quotation
3--Using references in function parameters
4--Reference as the return value of the function
1--The basic grammar of quotation
References are equivalent to aliasing variables, and their basic syntax is as follows:
type of data &alias = original name
# include <iostream> int main(){ int a = 10; int &b = a; std::cout << "a = " << a << std::endl; std::cout << "b = " << b << std::endl; b = 100; std::cout << "a = " << a << std::endl; std::cout << "b = " << b << std::endl; return 0; }
2--Notes on citations
① The reference must be initialized: for example, int &b; is wrong because it is not initialized;
② Once the reference is initialized, it cannot be changed: for example, int &b = a; indicates that b is an alias of a, and subsequent operations of int &b = c cannot be performed, that is, b cannot be changed to an alias of c;
# include <iostream> int main(){ int a = 10; int &b = a; int c = 20; b = c; // Assignment operation, not change of reference int &b = c; is change of reference, which is not allowed std::cout << "a = " << a << std::endl; std::cout << "b = " << b << std::endl; std::cout << "c = " << c << std::endl; return 0; }
3--Using references in function parameters
When a function passes parameters, references can be used to allow formal parameters to modify actual parameters. The advantage is that pointers can be simplified to modify actual parameters;
# include <iostream> // pass by value void mySwap01(int a, int b){ int temp = a; a = b; b = temp; } // address passing void mySwap02(int *a, int *b){ int temp = *a; *a = *b; *b = temp; } // pass by reference void mySwap03(int &a, int &b){ int temp = a; a = b; b = temp; } int main(){ int a = 10, b =20; std::cout << "Before exchange:" << std::endl; std::cout << "a = " << a << std::endl; std::cout << "b = " << b << std::endl; mySwap01(a, b); std::cout << "After value passing exchange:" << std::endl; std::cout << "a = " << a << std::endl; std::cout << "b = " << b << std::endl; mySwap02(&a, &b); std::cout << "After the address transfer exchange:" << std::endl; std::cout << "a = " << a << std::endl; std::cout << "b = " << b << std::endl; mySwap03(a, b); std::cout << "After the reference pass exchange:" << std::endl; std::cout << "a = " << a << std::endl; std::cout << "b = " << b << std::endl; return 0; }
The result of the reference transfer is a = 10, b = 20, this is because the address transfer has been performed before, so the value after the exchange is equivalent to the value before the exchange;
4--Reference as the return value of the function
Notes: Cannot return the reference of local variables, because local variables exist in the stack area, when the function is executed, the local variables will be released by the operating system; in the following example, test01 is wrong, but test02 is correct;
int &test01(){ int a = 10; // Local variables, which exist in the stack area return a; } int &test02(){ static int a = 10; // Static variables, which exist in the global zone return a; }
If the return value of the function is a reference, this function call can be used as an lvalue;
# include <iostream> int &test02(){ static int a = 10; // Static variables, which exist in the global zone return a; } int main(){ int &ref = test02(); // ref is an alias std::cout << "ref: " << ref << std::endl; test02() = 1000; // The left side of the = sign is an lvalue std::cout << "ref: " << ref << std::endl; }
5--The nature of citations
The essence of a reference is implemented in C++ as a pointer constant;
# include <iostream> // When found to be a reference, convert to int* const ref = &a; void func(int& ref){ ref = 100; // ref is a reference, converted to *ref = 100; } int main(){ int a = 10; // Automatic conversion to int* const ref = &a; The pointer constant point cannot be changed, which also explains why the reference cannot be changed int &ref = a; ref = 20; std::cout << "a: " << a << std::endl; std::cout << "ref: " << ref << std::endl; func(a); std::cout << "a = " << a << ", ref: " << ref << std::endl; return 0; }
6--Constant reference
Constant references are used to modify formal parameters to prevent misuse; in the function parameter list, use const to modify formal parameters, thereby preventing formal parameters from changing actual parameters;
# include <iostream> void showValue(int &val){ val = 1000; // this is a mistake std::cout << "val: " << val << std::endl; } int main(){ int a = 10; const int &ref1 = a; // The reference must refer to a legal memory space const int &ref2 = 20; // If you don't use const, you will report an error // Using const is equivalent to: // int temp = 20; // int &ref2 = temp; // After adding const, it is read-only and cannot be modified, that is, ref2 = 30 will report an error int b = 20; showValue(b); std::cout << "b = " << b << std::endl; return 0; }
# include <iostream> void showValue(const int &val){ // val = 1000; // This is a misoperation. After using const, if a misoperation is detected, an error will be reported std::cout << "val: " << val << std::endl; } int main(){ int a = 10; const int &ref1 = a; // The reference must refer to a legal memory space const int &ref2 = 20; // If you don't use const, you will report an error // Using const is equivalent to: // int temp = 20; // int &ref2 = temp; // After adding const, it is read-only and cannot be modified, that is, ref2 = 30 will report an error int b = 20; showValue(b); std::cout << "b = " << b << std::endl; return 0; }
Inside the showvalue() function, if there is no comment val = 1000, the following error will occur, reminding that the const constant reference is misoperated inside the function!