extern "c"
quote
Instead of defining a new variable, a reference gives an alias to an existing variable. The compiler will not open up memory space for the referenced variable. It shares the same memory space with the variable it references.
#include <iostream> using namespace std; // C + + standard library int main() { int a = 10; int& b = a; return 0; }
Changes in formal parameter variables affect arguments - pointers or references
#include <iostream> using namespace std; // C + + standard library int main() { int a = 10; int& b = a; int& c = a; int& d = b; c = 20; d = 30; return 0; }
Previous exchange writing
#include <iostream> using namespace std; // C + + standard library void Swap(int* p1, int* p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; } int main() { int x = 0, y = 1; Swap(&x, &y); }
Now – use the reference
void Swap(int& rx, int& ry) { int tmp = rx; rx = ry; ry = tmp; } int main() { int x = 0, y = 1; Swap(x, y); }
Write before stack initialization
typedef struct Stack { int* a; int top; int capacity; }ST; void StackInit(ST* ps) { ps->a = NULL; ps->top = ps->capacity = 0; } int main() { ST st; StackInit(&st); return 0; }
Stack initialization – use post reference writing
typedef struct Stack { int* a; int top; int capacity; }ST; void StackInit(ST& rs) { rs.a = NULL; rs.top = rs.capacity = 0; } int main() { int x = 0, y = 1; Swap(&x, &y); Swap(x, y); ST st; StackInit(st); SListNode* plist = NULL; SListPushBack(plist, 1); SListPushBack(plist, 2); return 0; }
Use of references in single linked lists
typedef struct SListNode { struct SListNode* next; int val; }SLTNode, *PSLTNode; //Void slistpushback (PSLTNode & phead, int x) -- this is not recommended. PSLTNode is a pointer to the structure diagram void SListPushBack(SLTNode*& phead, int x) { SLTNode* newnode; if (phead == NULL) { phead = newnode; } else { //... } } int main() { SListNode* plist = NULL; SListPushBack(plist, 1); SListPushBack(plist, 2); return 0; }
Alias pointer variable
int main() { int x = 0, y = 1; int* p1 = &x; int* p2 = &y; int*& p3 = p1; // Alias pointer variable *p3 = 10; p3 = p2; }
const and reference
- The condition that I become your alias: your read-write permission can be unchanged or reduced, but your read-write permission can't be enlarged
int main() { const int a = 10; int& b = a; // Become your alias and modify you (no) int c = 20; const int& d = c; // Become your alias without modifying you (line) }
- Aliases can be changed, but not all aliases have the same permissions as the original name (d only aliases, but cannot be modified)
Process of reference conversion
int main() { int i = 10; double d = i; const double& r = i; char ch = 0xff; int j = 0xff; int k = ch; // ch will be promoted and converted into int type, and then compared with the position symbol bit during promotion // Here we raise ch, do you turn ch into an int?, Is to generate a temporary variable int if (ch == j) { cout << "identical" << endl; } else { cout << "inequality" << endl; } return 0; }
Benefits of const
typedef struct Stack { int a[1000]; int top; int capacity; }ST; void StackInit(ST& s) // The purpose of passing references here is to change formal parameters and affect arguments { s.top = 0; s.capacity = 1000; // ... } void PrintStack(const ST& s) // 1. Reference passing is to reduce the copy of value passing and parameter passing // 2. You can protect parameters from being changed { // Suppose there is such a logic - > If const is referenced at time, it can be checked here //if (s.capacity = 0) / / it should have been = =, which was written carelessly= { } } void func(const int& n) // The second advantage of const as a parameter is that it can receive variables or constants { } int main() { ST st; StackInit(st); // ... PrintStack(st); int i = 10; const int j = 30; func(i); func(20); func(j); return 0; }
- Benefit 1
void PrintStack(const ST& s)
Add reference – void printstack (const st & S) does not need a pointer, but uses references to reduce the copy when passing values and parameters
Add const – it can protect the formal parameters from being changed. In case it is written as if(s.capacity=0) {}, the formal parameters will be changed
-
Benefit 2
The second advantage of const as a parameter is that it can receive variables or constants -
summary
If you want to reduce the copy of function parameters, you use reference parameters. If you don't change this parameter in the function, you'd better use const reference parameters
Reference as return value
Value transfer return
int Add(int a, int b) { int c = a + b; return c; } int main() { int ret = Add(1, 2); Add(3, 4); cout << "Add(1, 2) is :" << ret << endl; return 0; }
Value transfer return
int Add(int a, int b) { int c = a + b; return c; } int main() { const int& ret = Add(1, 2);//Temporary variables are constant, so you need to add const Add(3, 4); cout << "Add(1, 2) is :" << ret << endl; return 0; }
Reference return
- If the alias is returned without a return value, it may lead to cross-border access and uncertain results, because the stack frame is destroyed, and the value of – C is random
- Stack frames are not cleared on vs, and the result is 3
int& Add(int a, int b) { int c = a + b; return c; } int main() { int& ret = Add(1, 2);//ret is the alias of c //Add(3, 4); printf("hello world\n"); cout << "Add(1, 2) is :" << ret << endl; return 0; }
- Add another layer of reference to ret – vs. there is also an error
int& Add(int a, int b) { int c = a + b; return c; } int main() { int& ret = Add(1, 2); //Add(3, 4); printf("hello world\n"); cout << "Add(1, 2) is :" << ret << endl; return 0; }
Summary: when to use references
Test reference
It can't be measured once
#include <time.h> struct A { int a[10000]; }; void TestFunc1(A a){} void TestFunc2(A& a){} void TestRefAndValue() { A a; // Take value as function parameter size_t begin1 = clock(); TestFunc1(a); size_t end1 = clock(); // Take reference as function parameter size_t begin2 = clock(); TestFunc2(a); size_t end2 = clock(); // Calculate the time after the two functions run respectively cout << "TestFunc1(A)-time:" << end1 - begin1 << endl; cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl; }
The cpu is too fast
Repeat 10000 times, transfer 10000 bytes and reference 10000 times
#include <time.h> struct A { int a[10000]; }; void TestFunc1(A a){} void TestFunc2(A& a){} void TestRefAndValue() { A a; // Take value as function parameter size_t begin1 = clock(); for (size_t i = 0; i < 10000; ++i) TestFunc1(a); size_t end1 = clock(); // Take reference as function parameter size_t begin2 = clock(); for (size_t i = 0; i < 10000; ++i) TestFunc2(a); size_t end2 = clock(); // Calculate the time after the two functions run respectively cout << "TestFunc1(A)-time:" << end1 - begin1 << endl; cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl; }
References and pointers
int main() { int a = 10; int& ra = a; ra = 20; int* pa = &a; *pa = 30; return 0; }
- Understanding is OK